Pinia中文官网
准备工作:初始化一个Vue的项目
1.安装pinia
npm i --save pinia
2.引入并注册
// src/main.js
import { createApp } from 'vue'
import App from './App.vue'
import { createPinia } from 'pinia'
const pinia = createPinia()
// createApp(App).mount('#app')
const app = createApp(App)
app.use(pinia)
app.mount('#app')
3.创建store
// src/store/user.js
import { defineStore } from 'pinia'
export const useUserStore = defineStore('main',{})
//第一个参数是该store的唯一id(string)
//第二个参数是该store的配置项,配置store内的数据,修改数据的方法等等
4.使用store
在App.js使用store
// src/App.js
<script>
// 引入store: main
import { useUserStore } from './store/user'
export default {
name: 'App',
setup() {
const store = useUserStore()
console.log(store)
return {
store
}
}
}
</script>
5.在store中添加state
// src/store/user.js
import { defineStore } from 'pinia'
export const useUserStore = defineStore('main',{
state: () => {
return {
name:'孙悟空',
age: 18
}
}
})
//配置项中的state属性是一个函数,不能直接写成对象
6.操作state
1.读取state
<script>
import { useUserStore } from './store/user'
export default {
name: 'App',
setup() {
const store = useUserStore()
//console.log(store.name)
const {name} = store
//注意,直接解构的话不具有响应式
return {
store,
name
}
}
}
</script>
2.修改state
//使数据具有响应式
const { name } = storeToRefs(store)
// 1)直接修改
store.name = 'xxx'
// 2)批量修改
store.$patch = {
counter: store.counter + 1,
name: 'Abalam',
}
//但是,使用这种语法应用某些突变非常困难或代价高昂:任何集合修改(例如,从数组中推送、
//删除、拼接元素)都需要您创建一个新集合。 正因为如此,`$patch` 方法也接受一个函数来
//批量修改集合内部分对象的情况:
store.$patch((state) => {
state.items.push({ name: 'shoes', quantity: 1 })
state.hasChanged = true
})
// 3)替换state
store.$state = { counter: 666, name: 'Paimon' }
//或
pinia.state.value = {}
// 4)订阅状态
store.$subscribe((mutation, state) => {
// import { MutationType } from 'pinia'
mutation.type // 'direct' | 'patch object' | 'patch function'
// 与 store.$id 相同
mutation.storeId // 'cart'
// 仅适用于 mutation.type === 'patch object'
mutation.payload // 补丁对象传递给 to cartStore.$patch()
// 每当它发生变化时,将整个状态持久化到本地存储
localStorage.setItem('cart', JSON.stringify(state))
})
7.getters
Getter 完全等同于 Store 状态的 计算值(类似vue2的computed),在defineStore()的配置项中 1)基本使用
export const useStore = defineStore('main', {
state: () => ({
counter: 0,
}),
getters: {
doubleCount: (state) => state.counter * 2,
},
})
2)访问其他getter
export const useStore = defineStore('main', {
state: () => ({
counter: 0,
}),
getters: {
// 类型是自动推断的,因为我们没有使用 `this`
doubleCount: (state) => state.counter * 2, //这里不能使用this
doubleCountPlusOne() {
// 自动完成 ✨
return this.doubleCount + 1
},
},
})
3).给getter传递参数
export const useStore = defineStore('main', {
getters: {
getUserById: (state) => {
return (userId) => state.users.find((user) => user.id === userId)
},
},
})
//在组件中使用
<script>
export default {
setup() {
const store = useStore()
return { getUserById: store.getUserById }
},
}
</script>
<template>
<p>User 2: {{ getUserById(2) }}</p>
</template>
4)访问其他store的getter
import { useOtherStore } from './other-store'
export const useStore = defineStore('main', {
state: () => ({
// ...
}),
getters: {
otherGetter(state) {
const otherStore = useOtherStore()
return state.localData + otherStore.data
},
},
})
8.action
1)基本使用
import { defineStore } from 'pinia',
const useCounterStore = defineStore('counterStore', {
state: () => ({
counter: 0
}),
actions: {
increment() {
this.counter++
}
}
})
2)订阅action
使用 store.$onAction()
订阅 action 及其结果,其参数是一个回调函数,该回调函数会在action执行之前执行。
const unsubscribe = someStore.$onAction(
({
name, // action 的名字
store, // store 实例
args, // 调用这个 action 的参数
after, // 在这个 action 执行完毕之后,执行这个函数
onError, // 在这个 action 抛出异常的时候,执行这个函数
}) => {
// 记录开始的时间变量
const startTime = Date.now()
// 这将在 `store` 上的操作执行之前触发
console.log(`Start "${name}" with params [${args.join(', ')}].`)
// 如果 action 成功并且完全运行后,after 将触发。
// 它将等待任何返回的 promise
after((result) => {
console.log(
`Finished "${name}" after ${
Date.now() - startTime
}ms.\nResult: ${result}.`
)
})
// 如果 action 抛出或返回 Promise.reject ,onError 将触发
onError((error) => {
console.warn(
`Failed "${name}" after ${Date.now() - startTime}ms.\nError: ${error}.`
)
})
}
)
// 手动移除订阅
unsubscribe()
//当订阅action时会首先执行回调函数,然后执行action。
//`after` 是处理 Promise 的,允许在 action 完成后执行after函数
//`onError` 允许在处理中抛出错误。