状态管理
src/views/Pinia.vue
<script setup> import { ref } from "vue"; import { storeToRefs } from "pinia"; import { useCounterStore } from "../stores/counter"; import { useTodos } from "../stores/todos"; // 可以在组件中的任意位置访问 `store` 变量 const store = useCounterStore(); // const { count, doubleCount } = store; // `count` 和 `doubleCount` 没有响应式 let { count, doubleCount } = storeToRefs(store); // `count` 和 `doubleCount` 是响应式的 ref // 作为 action 的 increment 可以直接解构 const { increment } = store; store.count++; setTimeout(() => { count.value++; }, 2000); setTimeout(() => { increment(); }, 4000); const todoStore = useTodos(); const text = ref(""); function addTodo() { if (text != "") { todoStore.addTodo(text.value); text.value = ""; } } function updateStatus(item) { todoStore.$patch((state) => { for (var i in state.todos) { if (item == state.todos[i]) { state.todos[i]["isFinished"] = !state.todos[i]["isFinished"]; } } }); } function delTodo(item) { let tmp = []; for (var i in todoStore.todos) { if (item != todoStore.todos[i]) { tmp.push(todoStore.todos[i]); } } todoStore.$patch({ todos: tmp }); } todoStore.$subscribe((mutation, state) => { // 每当状态发生变化时,将整个 state 持久化到本地存储。 localStorage.setItem("todos", JSON.stringify(state)); }); </script> <template> <div> <div> <p>count:{{ count }}</p> <p>doubleCount:{{ doubleCount }}</p> <p>store.count:{{ store.count }}</p> <p>store.doubleCount:{{ store.doubleCount }}</p> <!-- 重置 state --> <button @click="store.$reset">重置</button> </div> <div> <p><input v-model="text" placeholder="edit me" @keyup.enter="addTodo" /></p> <ul> <li v-for="item in todoStore.filteredTodos" :key="item.id"> {{ item.text }} <a v-if="item.isFinished">完成</a> <a v-else @click="updateStatus(item)">未完成</a> <a @click="delTodo(item)">删除</a> </li> </ul> <!-- 变更 state --> <button @click="todoStore.$patch({ filter: 'all' })">All</button> <button @click="todoStore.$patch({ filter: 'finished' })">Finished</button> <button @click="todoStore.$patch({ filter: 'unfinished' })">Unfinished</button> <!-- 重置 state --> <button @click="todoStore.$reset">重置</button> </div> </div> </template> <style scoped> span, a { margin-left: 1rem; } a { cursor: pointer; } </style>
src/stores/counter.js
import { defineStore } from "pinia"; import { ref, computed } from "vue"; export const useCounterStore = defineStore("counter", () => { const count = ref(0); function increment() { count.value++; } const doubleCount = computed(() => count.value * 2); //在 Setup Stores 中,需要创建自己的 $reset() 方法,Option Store不需要手段创建 function $reset() { count.value = 0; } return { count, doubleCount, increment, $reset }; });
src/stores/todos.js
import { defineStore } from "pinia"; export const useTodos = defineStore("todos", { state: () => ({ /** @type {{ text: string, id: number, isFinished: boolean }[]} */ todos: [], /** @type {'all' | 'finished' | 'unfinished'} */ filter: "all", // 类型将自动推断为 number nextId: 0, }), getters: { finishedTodos(state) { // 自动补全! ✨ return state.todos.filter((todo) => todo.isFinished); }, unfinishedTodos(state) { return state.todos.filter((todo) => !todo.isFinished); }, /** * @returns {{ text: string, id: number, isFinished: boolean }[]} */ filteredTodos() { if (this.filter === "finished") { // 调用其他带有自动补全的 getters ✨ return this.finishedTodos; } else if (this.filter === "unfinished") { return this.unfinishedTodos; } return this.todos; }, }, actions: { // 接受任何数量的参数,返回一个 Promise 或不返回 addTodo(text) { // 你可以直接变更该状态 this.todos.push({ text, id: this.nextId++, isFinished: false }); }, }, });
标签:count,text,学习,state,store,Pinia,vue3,todos,doubleCount From: https://www.cnblogs.com/caroline2016/p/17928488.html