参考链接:https://juejin.cn/post/7121209657678364685
Pinia官方:https://pinia.vuejs.org/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 pinia
piniaStoreA.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); //xiaoyue
piniaStoreA.$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 } = piniaStoreA
piniaStoreA.$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 时,通过this
return 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 = 2
console.log(piniaStoreA.sum)