Pinia 状态管理
store、actions、与 Redux 对照。
30 分钟
Pinia 状态管理
这一课你将能做到
- 用组合式写法定义 Pinia store,在组件中读写状态与 actions
- 用
storeToRefs解构保持响应式 - 对照 Redux/React Context:何时需要全局 store,何时组件内 state 足够
为什么要学
跨页、跨组件共享的数据(当前用户、购物车、Todo 列表)若层层 props 会很烦。
Pinia 是 Vue 3 官方推荐的状态库,API 比早期 Vuex 轻。本站 React 侧常用局部 state + Context;学 Pinia 是为了读懂 Vue 中后台项目。
先建立图像
组件 A ──┐
组件 B ──┼─ useTodoStore() ──> 同一份 state
路由页 ──┘
| 概念 | 人话 |
|---|---|
| state | 全局记得的数据 |
| getters | 类似 computed |
| actions | 改状态/异步的方法 |
跟着做
步骤 1:安装与注册
npm install pinia
import { createPinia } from "pinia";
app.use(createPinia());
create-vue 勾选则已就绪。
步骤 2:定义 store
// stores/todo.js
import { defineStore } from "pinia";
import { ref, computed } from "vue";
export const useTodoStore = defineStore("todo", () => {
const items = ref([]);
const filter = ref("all");
const visible = computed(() => {
if (filter.value === "active") return items.value.filter((t) => !t.done);
if (filter.value === "done") return items.value.filter((t) => t.done);
return items.value;
});
function add(text) {
const t = text.trim();
if (!t) return;
items.value.push({ id: Date.now(), text: t, done: false });
}
function toggle(id) {
const row = items.value.find((x) => x.id === id);
if (row) row.done = !row.done;
}
return { items, filter, visible, add, toggle };
});
这是 setup store 风格,与组件组合式一致。
步骤 3:组件使用
<script setup>
import { storeToRefs } from "pinia";
import { useTodoStore } from "../stores/todo";
const store = useTodoStore();
const { visible, filter } = storeToRefs(store);
</script>
<template>
<input
@keyup.enter="
store.add($event.target.value);
$event.target.value = '';
"
/>
<button
v-for="f in ['all', 'active', 'done']"
:key="f"
type="button"
@click="filter = f"
>
{{ f }}
</button>
<ul>
<li v-for="t in visible" :key="t.id">
<label>
<input type="checkbox" :checked="t.done" @change="store.toggle(t.id)" />
{{ t.text }}
</label>
</li>
</ul>
</template>