参考链接:/post/7121209657678364685
Pinia官方:/zh/introduction.html
一、安装
npm i pinia -S
二、main.js 引入
import {createApp } from "vue"import App from "./App.vue"import {createPinia } from 'pinia'const pinia = createPinia()createApp(App).use(pinia).mount("#app")
三、创建 store
可通过defineStore
创建多个 store
(这与 vuex 只可以创建一个 store不同),所以不再需要 modules
(每个 store 便是一个模块)不再使用 mutations
作为 直接修改state 的方式支持以往的options
创建形式,也可以使用组合式函数
定义一个store(像 setup 一样)1、通过 options 创建
例如在 src下新建 piniaStore/storeA.js
import {defineStore } from "pinia";export const storeA = defineStore("storeA", {state: () => {return {piniaMsg: "hello pinia",};},getters: {},actions: {},})
2、通过组合式函数创建
ref()
就是state
属性computed()
就是getters
function()
就是actions
export const useCounterStore = defineStore('counter', () => {const count = ref(0)function increment() {count.value++}return {count, increment }})
四、获取状态
1、在 <script setup> 中
<template><div></div></template><script setup>import {storeA } from '@/piniaStore/storeA'let piniaStoreA = storeA()console.log(piniaStoreA.piniaMsg); //hello pinia</script>
2、在 setup( ) 中
<script>import {useCounterStore } from '../stores/counter'export default defineComponent({setup() {const counterStore = useCounterStore()return {counterStore }},computed: {quadrupleCounter() {return this.counterStore.count * 2},},methods: {incrementAndPrint() {// 使用方法、状态,通过整个 store(因为没有解构)this.counterStore.increment()console.log('New Count:', this.counterStore.count)},},})</script>
五、修改状态
1、直接赋值修改
<template><div>{{piniaStoreA.piniaMsg }}</div></template><script setup>import {storeA } from '@/piniaStore/storeA'let piniaStoreA = storeA()console.log(piniaStoreA.piniaMsg); //hello piniapiniaStoreA.piniaMsg = 'hello juejin'console.log(piniaStoreA.piniaMsg); //hello juejin</script>
2、使用 $patch 修改单个或多个状态
可传入对象
修改import {defineStore } from "pinia";export const storeA = defineStore("storeA", {state: () => {return {piniaMsg: "hello pinia",name: "xiaoyue",};},getters: {},actions: {},});
import {storeA } from '@/piniaStore/storeA'let piniaStoreA = storeA()console.log(piniaStoreA.name); //xiaoyuepiniaStoreA.$patch({piniaMsg: 'hello juejin',name: 'daming'})console.log(piniaStoreA.name);//daming
也可传入函数
修改
import {storeA } from '@/piniaStore/storeA'let piniaStoreA = storeA()piniaStoreA.$patch((state) => {state.name = 'daming'state.piniaMsg = 'hello juejin'})
3、在 actions 中进行修改
Pinia去掉了 mutations
,所以在actions
中修改 state 就行使用actions
时,像调用 methods 一样直接调用即可import {defineStore } from "pinia";export const storeA = defineStore("storeA", {state: () => {return {piniaMsg: "hello pinia",name: "xiao yue",};},actions: {setName(data) {this.name = data;},},});
// script中使用import {storeA } from '@/piniaStore/storeA'let piniaStoreA = storeA()piniaStoreA.setName('daming')
<!-- 模板中使用 --><button @click="piniaStoreA.setName()">点击</button>
4、使用 $reset 重置 state
Pinia 可以使用$reset
将状态重置为初始值
import {storeA } from '@/piniaStore/storeA'let piniaStoreA = storeA()piniaStoreA.$reset()
六、解构
在上述使用中,我们都是通过整个 store
来使用内部的 state 等,怎么解构使用呢?
1、错误示范
传统的ES6解构
会使 state失去响应式
<template><div>{{name }}</div></template><script setup>import {storeA } from '@/piniaStore/storeA'let piniaStoreA = storeA()let {piniaMsg, name } = piniaStoreApiniaStoreA.$patch({name: 'daming' // 更新失败})</script>
2、正确方式
Pinia 提供了一个解构方法storeToRefs
<template><div>{{name }}</div></template><script setup>import {storeA } from '@/piniaStore/storeA'import {storeToRefs } from 'pinia'let piniaStoreA = storeA()let {piniaMsg, name } = storeToRefs(piniaStoreA)piniaStoreA.$patch({name: 'daming'})</script>
七、getters
1、使用 getters
Pinia 中的 getters和 Vuex 的 getters 用法是一致的
, 也具有缓存
特性getter1 访问 getter2 时,通过this
import {defineStore } from "pinia";export const storeA = defineStore("storeA", {state: () => {return {count1: 1,count2: 2,};},getters: {sum (state) {console.log('我被调用了!')return state.count1 + state.count2;},sum2 () {// 访问其他 getter 时,通过thisreturn this.sum + 1}},});
<template><div>{{piniaStoreA.sum }}</div></template><script setup>import {storeA } from '@/piniaStore/storeA'let piniaStoreA = storeA()console.log(piniaStoreA.sum) //3</script>
2、 缓存验证
import {storeA } from '@/piniaStore/storeA'let piniaStoreA = storeA()console.log(piniaStoreA.sum)console.log(piniaStoreA.sum)console.log(piniaStoreA.sum)piniaStoreA.count1 = 2console.log(piniaStoreA.sum)
八、辅助函数
若你更倾向于使用选项式API
,可以试试 Pinia 的映射辅助函数
,具体使用方式请 查看下一篇