使用vite 构建项目
npm init vite@latest my-vue-app -- --template vue
选择 vue —> vue + ts
项目中添加 pinia
npm install pinia
目录结构
- src
- api
- assets
- components
- Home.vue
- store
- index.ts
store 为全局仓库定义处,使用的时候 都需要从此处引入,可以多人维护一个,也可以每个人单独维护一个自己的 store,即在自己负责的组件或模块中,同此全局仓库的定义方法和使用方法相同,只在引入的时候使用不同的仓库名即可。
挂载 pinia
// main.ts
import { createApp } from 'vue'
import App from './App.vue'
import {createPinia} from 'pinia'
const pinia = createPinia()
const app = createApp(App);
app.use(pinia);
app.mount('#app');
引入的时候,一共有以下几种方法
// 在使用前需要先实例化
import {mainStore} from './../store/index'
const store = mainStore();
直接解构
使用 点语法访问
使用 storeToRefs
$path
store.$patch({
counter: store.counter + 1,
name: 'Abalam',
})
cartStore.$patch((state) => {
state.items.push({ name: 'shoes', quantity: 1 })
state.hasChanged = true
})
$state
store.$state = { counter: 666, name: 'Paimon' }
store.state.value = {}
方法
在 getter 和actions 中 都可以通过 this 访问到当前 pinia中的 其他 getter 和 actions中的函数,实现相互调用
pinia中的 getter
// 通过getter 获得计算以后的数据
getters: {
// 获取计算以后的属性
getData(state):boolean{
return !this.data.msg
},
// 通过传值的方式获取计算以后的属性
getCurrentData(state){
return (bool:boolean) => {
return this.data.msg = bool
}
}
}
pinia中的 actions
import { mainStore } from '../../material_show/pinia'
actions: {
setMainStore() {
//可以直接引入其他仓库的pinia,获取其值或调用getter和actions
++mainStore().stuRefresh;
++mainStore().parRefresh;
},
// 更改用户登录状态
changeUserStatus(bool:boolean){
this.userStatus = bool;
},
// 更新教师信息
updateTeacher(options:teacherType){
this.teacherDetail = {...options};
},
}
const piniaSymbol = Symbol('pinia')
function createPinia() {
let pinia = {
install(app) {
app.provide(piniaSymbol, pinia)
},
state: ref({}), // store 中的 state
_s: new Map() // 存储每一个 store
}
return pinia
}
function defineStore(id, options) {
function useStore() { ... }
return useStore
}
function useStore() {
let pinia = inject(piniaSymbol) // piniaSymbol 为在 createPina 代码段内声明的全局变量
if (!pinia._s.get(id)) { // 当 pinia._s.get(id) 获取不到值时在判断内部设置上
// 将 store 存储到 pinia._s 内,并合并state/getters/actions 到一个对象中
createOtionsStore(id, options, pinia)
}
let store = pinia._s.get(id) // 获取到处理后 store 将其 return
return store
}
function createOtionsStore(id, options, pinia) {
let store = reactive({
_p: pinia,
id
}) // 创建 store
Object.assign(store, setup()) // 将 setup 的返回值通过 Object.assign 合并到 store 对象中
pinia._s.set(id, store) // 将 处理后的 store 存储到 pinia._s 中
function setup() { ...... }
}
function setup() {
// 将 需要用到的 state/getters/actions 从 options 中解构出来
const { state, getters, actions } = options
// 判断 pinia.state.value 中是否有值,如果没值则将 state 的调用结果赋值进去
!pinia.state.value[id] && (pinia.state.value[id] = state())
// 此时通过 toRefs 将 pinia.state.value[id] 处理为响应式的,暂存与 localState
let localState = toRefs(pinia.state.value[id])
// 处理getters 时先拿到内部所有的 key 组成的数组,并遍历给其包装为 computed
let localGetters = Object.keys(getters).reduce((item, name) => {
item[name] = computed(() => {
const store = pinia._s.get(id)
// 通过 call 将 getters 内部方法的 this 指向了store,并给其传递了唯一的参数 也就是 store 自身
return getters[name].call(store, store)
})
return item
}, {})
// 此处将 处理后的 state/getters/actions 返回
return Object.assign(localState, localGetters, actions)
}