Pinia 是 Vue 的存储库,它允许您跨组件/页面共享状态。
安装: yarn add pinia 或者 npm add pinia
注意,如果是vue2 需要安装 Api : @vue/composition-api
采用了组合式APi 的写法。
import { createPinia } from "pinia" ;
Vue.use( createPinia() );
注意,vue2 需要使用下面这种写法
import { cratePinia , PiniaVuePlugin } from "pinia" ;
Vue.use(PiniaVuePlugin);
const pinia = createPinia();
new Vue({
el:'#app',
...
pinia,
})
Store
一个Store 就是一个(pinia)实体,它持有未绑定到组件树的状态和业务逻辑,它托管了全局的状态, 它有点像一个始终存在,并且每个人可以读写的组件。它主要有三个概念,stata , getters 和 actions (数据,计算,方法)。
和Vuex 的区别
去掉了 mutations 。
创建一个 store
defineStore()
import { defineStore } from 'pinia';
// main 应该是应用程序中,store的唯一ID。
export const useStore = defineStore('main' , { // 定义store
stata:()=>{
return {
conunt:1
]
]
})
import {useStore} from "./store/index.ts"
import {ref} from 'vue'
const useList = useStroe()
console.log(useList.conunt)
import { defineStore } from 'pinia';
import { ref } from 'vue';
export const useState = defineStore('main',()=>{ // 定义store
const state = ref({count:30}) // 定义state
})
import {useStore} from "./store/index.ts"
import {ref} from 'vue'
const useList = useStroe()
console.log(useList.state.count)
使用 store
一旦 store 被实例化,你就可以直接在 store 上 访问 state,getters 和 actions 中定义的任何属性。
<script setup>
import userStore from '@/stotes/counter' // 导入store 所在的文件
export default {
const store = useStore(); // 可以根据需要定义任意数量的store变量
const { name, doubleCount } = store // 会失去响应式
}
</script>
- ****可以根据需要定义任意数量的 store ,并且
您应该在不同的文件中定义每个 store以充分利用 pinia - store 返回的是一个用
reactive包裹的对象,所以,不可以对 store 直接进行解构,会失去数据的响应式 。 - 如果想从store 中取值,并且保持响应式,需要使用
storeToRefs()
<script setup>
import { storeToRefs } from 'pinia' ;
export default {
// 会保持响应式 , 这也会为插件添加的属性创建引用
// 但跳过任何 action 或 非响应式(不是 ref/reactive)的属性
const { naem , doubleCount } = storeToRefs ( store )
}
</script>
state
state 是 store 的核心内容,它定义了应用程序的初始状态,是一个Function。
import { defineStore } from 'pinia'
const useStore = defineStore('storeId',{
stete :()=>{
return {
// ... 初始值,例如 name : '小明'
}
}
})
使用stata
// Example File Path:
// ./src/stores/counterStore.js
import { defineStore } from 'pinia',
const useCounterStore = defineStore('counterStore', {
state: () => ({
counter: 0
})
})
import { defineStore } from 'pinia';
import { ref } from 'vue';
export const useState = defineStore('main',()=>{ // 定义store
const state = ref({count:30}) // 定义state
return{state}
})
<!-- 使用 store 和 state -->
<script >
import { useCounterStore } from '../stores/counterStore'
// 在组件内部引入 store 即可使用state中定义的属性
export default {
const counterStore = useCounterStore()
computed: {
tripleCounter() {
return counterStore.counter * 3
},
},
}
</script>
修改state的值还可以使用 $patch () $patch 的参数可以是对象,也可以是Fuction,
store.$patch((state) => {
state.items.push({ name: 'shoes', quantity: 1 })
state.hasChanged = true
})
替换 state
store.$state = {counter : 666 , name : 'Paimon'}
Getters
Getter 完全等同于 Store 状态的 计算值。 它们可以用 defineStore() 中的 getters 属性定义。 他们接收“状态”作为第一个参数以鼓励箭头函数的使用
export const useStore = defineStore('main', {
state: () => ({
counter: 0,
}),
getters: {
doubleCount: (state) => state.counter * 2,
},
})
import { defineStore } from 'pinia';
import { ref , computed } from 'vue';
export const useState = defineStore('main',()=>{ // 定义store
const state = ref({count:30}) // 定义state
const getState = Computed(()=>{
return state.count.value ++
})
rutern {state , getState}
})
大多数时候,getter 只会依赖状态,但是,他们可能需要使用其他 getter。 正因为如此,我们可以在定义常规函数时通过 this 访问到整个 store 的实例
export const useStore = defineStore('main', {
state: () => ({
counter: 0,
}),
getters: {
// 自动将返回类型推断为数字
doubleCount(state) {
return state.counter * 2
},
// 返回类型必须明确设置
doublePlusOne(): number {
return this.counter * 2 + 1
},
},
})
在组件中导入store 后,可以直接访问store 中定义的 getters。
Actions
定义操作 state 的方法。相当于组件中的 methods。 它们可以使用 defineStore() 中的 actions 属性定义,并且它们非常适合定义业务逻辑:
actions 支持 同步和异步,可以通过this访问state中定义的值
export const useStore = defineStore('main', {
state: () => ({
counter: 0,
}),
actions: {
increment() {
this.counter++
},
randomizeCounter() {
this.counter = Math.round(100 * Math.random())
},
},
})
import { defineStore } from 'pinia';
import { ref , computed } from 'vue';
export const useState = defineStore('main',()=>{ // 定义store
const state = ref({count:30}) // 定义state
const getState = Computed(()=>{
return state.value.count. ++
})
function test (){
console.log(state.value)
}
rutern {state , getState ,test}
})