完成效果:
安装 pinia:npm i pinia
在 main.ts
中配置:
typescriptimport { createApp } from 'vue';
import App from './App.vue';
import { createPinia } from 'pinia';
const pinia = createPinia();
createApp(App).use(pinia).mount('#app');
@/store/count.ts
typescriptimport { defineStore } from 'pinia';
export const useCountStore = defineStore('count', {
state() {
return {
count: 1
}
}
});
@/store/sentence.ts
typescriptimport { defineStore } from 'pinia';
export const useSentenceStore = defineStore('sentence', {
state() {
return {
sentenceList: [
{ id: 'xxx1', content: '长河千嶂,大荒孤城,历历在目。' },
{ id: 'xxx2', content: '回首某个瞬间,下个瞬间即告消逝。' },
{ id: 'xxx3', content: '无欲无求,笑口常开。' }
]
}
}
});
@/component/Count.vue
vue<template> <div class="count"> <h2>当前计数为:{{ countStore.count }}</h2> <select v-model.number="n"> <option value="1">1</option> <option value="2">2</option> <option value="3">3</option> </select> <button @click="add">加</button> <button @click="sub">减</button> </div> </template> <script setup lang="ts"> import { ref } from 'vue'; import { useCountStore } from '@/store/count'; const countStore = useCountStore(); // countStore 是一个 reactive 对象 // console.log('countStore',countStore) // 以下都可以拿到 state 数据 // console.log('countStore.count', countStore.count) // console.log('countStore.$state.count',countStore.$state.count) let n = ref(1); function add() { } function sub() { } </script> <style scoped> .count { background-color: skyblue; border-radius: 10px; box-shadow: 0 0 10px; padding: 20px; } select,button { margin: 0 5px; height: 26px; } </style>
@/component/Sentence.vue
vue<template> <div class="sen"> <button @click="getSen">获取一句话</button> <ul> <li v-for="sen in sentenceStore.sentenceList" :key="sen.id">{{sen.content}}</li> </ul> </div> </template> <script setup lang="ts"> import { useSentenceStore } from '@/store/sentence'; const sentenceStore = useSentenceStore(); function getSen() { } </script> <style scoped> .sen { background-color: orange; border-radius: 10px; box-shadow: 0 0 10px; padding: 20px; } </style>
store.sum += 1
store.$patch({ sum: 888, name: '小明'})
配置 actions (配置项式),常用于公共代码较多可以封装的情况
typescript/* @/store/count.ts */
export const useCountStore = defineStore('count', {
actions: {
increment(value: number) {
this.count += value;
}
},
state() {
return {
count: 1
}
}
});
/* @/component/Count.vue */
countStore.increment(1);
直接解构会丢失响应式,而直接使用 toRefs
会将 store 中的所有属性全部转为 ref 对象
typescriptconst { count } = storeToRefs(countStore);
function add() {
countStore.$patch({count: count.value + n.value})
}
function sub() {
count.value -= n.value;
}
getters
为一个对象,相当于可共享的计算属性,可以被 storeToRefs
拿到
typescriptexport const useCountStore = defineStore('count', {
state() {
return {
count: 1
}
},
getters: {
bigCount: state => state.count * 10,
largeCount(): number {
return this.count * 10;
}
}
});
类比 watch
监视
typescriptsentenceStore.$subscribe((mutate, state) => {
console.log('sentenceStore变化了', mutate, state)
})
将 defineStore
封装成组件的 setup
写法
typescriptimport { defineStore } from 'pinia';
import { ref } from 'vue';
export const useCountStore = defineStore('count', () => {
let count = ref(1);
function increment(value: number) {
count.value += value;
}
return { count, increment };
});
如果两个或更多的 store 相互使用,它们不可以通过 getters 或 actions 创建一个无限循环。它们也不可以同时在它们的 setup 函数中直接互相读取对方的 state
本文作者:Morales
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 License 许可协议。转载请注明出处!