# vue3电商网站 **Repository Path**: rowrey/vue3-e-commerce-website ## Basic Information - **Project Name**: vue3电商网站 - **Description**: vue3 vite电商项目 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2023-09-18 - **Last Updated**: 2023-09-18 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ### reactive ref 响应式 ### 1,computed - computed(item=>item > 2) ### 2,watch 监听 - immediate 立即出发回调 - deep 深度监听(慎用) ```javascript watch( state, () => { console.log('数据变化了') }, { deep: true, immediate: true, } ) ``` - 可以对单个值深度监听 ```javascript watch( () => state.msg, () => { console.log('state.msg 改变了') } ) ``` - 监听多个 watch([count, name], ([newCount, newName],[oldCount,oldName])=>{}) ### 3 父传子 - defineProps({}) const props = defineProps({}) ### 4 子传父 - defineEmits([]) - 父组件 const changeMsg = (sonmsg) => { msg.msg = sonmsg } - 子组件 const emit = defineEmits(['change-Msg']) const sendMsgs = () => { emit('change-Msg','this is new msg') } ### 5 Ref defineExpose - 当父组件 ref 的目标是一个子组件时 如果想访问子组件的内容,需要在子组件用 defineExpose 暴露出来 ### 6 provide 和 inject - provide('key', msg) - inject('key') ### 7 状态管理 pinia npm install pinia ```javascript import { createApp } from 'vue' import { createPinia } from 'pinia' const pinia = createPinia() const app = createApp(App) app.use(pinia) app.mount('#app') ``` stroe/counter.js ```javascript import { defineStore } from 'pinia' import { ref } from 'vue' export const useCounterStore = defineStore('counter', () => { // 定义数据 const count = ref(0) // 定义修改数据的方法(action同步+异步) const add = () => { count.value++ } // 异步请求 和组件里面写请求一样直接axios调用return出去就行 // 以对象的方式return供组件使用 return { count, add, } }) // 页面使用 import { useCounterStore } from '@/store/counter.js' const counterStore = useCounterStore() // counterStore如果需要使用响应式解构赋值(只处理数据 不处理方法 方法还得从原来的里面解构 不需要包裹) 需要使用storeToRefs()包裹 // import { storeToRefs } from 'pinia' // const { xxx } = storeToRefs(counterStore) //这样的解构赋值才是响应式的 不使用解构赋值则不需要 ``` ### 8 element-plus 自动按需导入配置 - npm install -D unplugin-vue-components unplugin-auto-import // 安装插件 ```javascript // vite.config.ts import { defineConfig } from 'vite' import AutoImport from 'unplugin-auto-import/vite' import Components from 'unplugin-vue-components/vite' import { ElementPlusResolver } from 'unplugin-vue-components/resolvers' export default defineConfig({ // ... plugins: [ // ... AutoImport({ resolvers: [ElementPlusResolver()], }), Components({ resolvers: [ElementPlusResolver()], }), ], }) ``` ### 9 改变 elementplus 默认主题颜色 - npm i sass -D - npm i unplugin-element-plus - styles/element/index.scss ```scss /* 只需要重写你需要的即可 */ @forward 'element-plus/theme-chalk/src/common/var.scss' with ( $colors: ( 'primary': ( // 主色 'base': #27ba9b, ), 'success': ( // 成功色 'base': #1dc779, ), 'warning': ( // 警告色 'base': #ffb302, ), 'danger': ( // 危险色 'base': #e26237, ), 'error': ( // 错误色 'base': #cf4444, ), ) ); ``` - 自动导入配置 vite.config.js ```javascript // 导入对应包 import ElementPlus from 'unplugin-element-plus/vite' plugins: [ Components({ resolvers: [ElementPlusResolver({ importStyle: 'sass' })], }), // 按需定制主题配置 ElementPlus({ useSource: true, }), ], css: { preprocessorOptions: { scss: { // 自动导入定制化样式文件进行样式覆盖 additionalData: ` @use "@/styles/element/index.scss" as *; `, } } } ``` ### 10 eslintrc.cjs 中配置 rules: { 'vue/multi-word-component-names': 0 // 不再强制要求组件命名 } ### 11 scss 变量自动导入 - 自动导入后 文件使用 scss 变量的时候就不用每一个都导入文件,直接使用即可 - var.scss $warnColor:#ffb302; - vite.config.js ```javascript css: { preprocessorOptions: { scss: { // 自动导入 scss 文件 additionalData: `@use "@/styles/var.scss" as *;`, } } } ``` ### 12 阿里字体库使用 - 登录阿里字体图标网站 选取自己的图标 生成链接放到 index.html ### 13 vueuse 的使用 - npm i @vueuse/core // 根据 window 获取滚动 y 的值 import { useScroll } from '@vueuse/core' const { y } = useScroll(window) ### 14 图片懒加载自定义指令 - 添加指令 directive/index.js ```javascript import { useIntersectionObserver } from '@vueuse/core' // 定义全局指令 图片懒加载 export const lazyPlugin = { install(app) { app.directive('img-lazy', { mounted(el, binding) { // el:指代img元素 // binding:指代指令后面绑定的表达式的值 // 基于@vueuse/core,判断加载图片是否进入视图 const { stop } = useIntersectionObserver( el, //目标对象 ([{ isIntersecting }]) => { // 是否进入视图区域 if (isIntersecting) { el.src = binding.value // 赋值之后停止监听 stop() } } ) }, }) }, } ``` - main.js 里面添加指令 import { lazyPlugin } from '@/directive' app.use(lazyPlugin) - 页面使用 ### 15 全局注册组件 与 图片懒加载指令相似 - components 文件夹下 index.js 当要使用 components 文件夹下的组件时 不用在文件里面导入 ```javascript import ImageView from './ImageView/index.vue' // import Sku from './Sku' export const useComponents = { install(app) { //app.component(组件名字, 组件配置对象) app.component('useImageView', ImageView) // app.component('useSku',Sku) }, } ``` - main.js 全局注册组件 import { useComponents } from '@/components' app.use(useComponents) ### 16 路由缓存问题 当路由 path 一样,参数不同的时候会选择直接复用路由对应的组件 解决方案: 1. 给 routerv-view 添加 key 属性,破坏缓存 页面所以请求都会重新发送(暴力) 2. 使用 onBeforeRouteUpdate 钩子函数,做精确更新 ```javascript import { onBeforeRouteUpdate } from 'vue-router' onBeforeRouteUpdate((to) => { //执行需要改变的方法 并传递跳转之后的路由参数 getBread(to.params.id) }) ``` ### 17 路由滚动行为定制 - 页面切换时 滚动到中间部分时 切换页面需要置顶 scrollBehavior() { return { top: 0 } } ### 18 与元素为目标的响应式鼠标位置 useMouseInElement import { useMouseInElement } from '@vueuse/core' const target = ref(null)// target 为 dom 元素 const { elementX, elementY, isOutside } = useMouseInElement(target) - 参数 x: 730 y: 645 sourceType: 'mouse' elementX: 362 elementY: 237 elementPositionX: 368 elementPositionY: 408 elementHeight: 160 elementWidth: 160 isOutside: true ### 19 pinia 持久化 - npm i pinia-plugin-persistedstate //官网 https://prazdevs.github.io/pinia-plugin-persistedstate/zh/guide/ ```javascript import piniaPluginPersistedstate from 'pinia-plugin-persistedstate' const pinia = createPinia() pinia.use(piniaPluginPersistedstate) // 仓库使用 export const useUserStore = defineStore('user', () => {}, { persist: true, // 添加这句即可 }) ``` ### 20 v-model 双向绑定指令不方便命令式操作,使用:model-value 和@change 配合使用 ### 21 格式化时间 - npm i dayjs