项目代码: https://gitee.com/rowrey/vue3-e-commerce-website.git
watch(
state,
() => {
console.log('数据变化了')
},
{
deep: true,
immediate: true,
}
)
watch(
() => state.msg,
() => {
console.log('state.msg 改变了')
}
)
npm install pinia
import { createApp } from 'vue'
import { createPinia } from 'pinia'
const pinia = createPinia()
const app = createApp(App)
app.use(pinia)
app.mount('#app')
stroe/counter.js
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) //这样的解构赋值才是响应式的 不使用解构赋值则不需要
// 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()],
}),
],
})
/* 只需要重写你需要的即可 */
@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,
),
)
);
// 导入对应包
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 *;
`,
}
}
}
rules: {
‘vue/multi-word-component-names’: 0 // 不再强制要求组件命名
}
css: {
preprocessorOptions: {
scss: {
// 自动导入 scss 文件
additionalData: `@use "@/styles/var.scss" as *;`,
}
}
}
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()
}
}
)
},
})
},
}
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)
},
}
当路由 path 一样,参数不同的时候会选择直接复用路由对应的组件
解决方案:
import { onBeforeRouteUpdate } from 'vue-router'
onBeforeRouteUpdate((to) => {
//执行需要改变的方法 并传递跳转之后的路由参数
getBread(to.params.id)
})
import { useMouseInElement } from ‘@vueuse/core’
const target = ref(null)// target 为 dom 元素
const { elementX, elementY, isOutside } = useMouseInElement(target)
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
const pinia = createPinia()
pinia.use(piniaPluginPersistedstate)
// 仓库使用
export const useUserStore = defineStore('user', () => {}, {
persist: true, // 添加这句即可
})