4.2 Pinia 与共享状态
本章目标: 用 store 共享多个页面需要的状态,避免把所有状态都塞进全局。
先判断是否需要共享
| 状态 | 通常放在哪里 |
|---|---|
| 表单输入、弹窗是否显示 | 当前组件 |
| 一块业务区域的请求状态 | 组合式函数或页面 |
| 页面可分享的筛选条件 | URL query |
| 当前用户、跨页面偏好 | Pinia |
| 数据库里的真实任务 | 服务端,前端只是缓存 |
Pinia 是 Vue 官方推荐的状态管理库。它不能代替数据库,也不会自动把内存状态持久化到浏览器。
安装与注册
npm install pinia
在 main.ts 现有应用上注册:
src/main.ts(接续 Router 章节)
import { createApp } from 'vue';
import { createPinia } from 'pinia';
import App from './App.vue';
import { router } from './router';
createApp(App).use(createPinia()).use(router).mount('#app');
声明 Setup Store
src/stores/preferences.ts
import { computed, ref } from 'vue';
import { defineStore } from 'pinia';
export const usePreferencesStore = defineStore('preferences', () => {
const hideCompleted = ref(false);
const description = computed(() => hideCompleted.value ? '仅显示未完成' : '显示全部');
function toggleVisibility() {
hideCompleted.value = !hideCompleted.value;
}
return { hideCompleted, description, toggleVisibility };
});
store ID 在应用里应唯一。ref 类似 state,computed 类似 getter,函数类似 action。Setup Store 的状态应返回给 Pinia 管理,不要把需要管理的状态藏在闭包里。
组件里使用
可放入任一已注册 Pinia 的页面
<script setup lang="ts">
import { storeToRefs } from 'pinia';
import { usePreferencesStore } from '../stores/preferences';
const preferences = usePreferencesStore();
const { hideCompleted, description } = storeToRefs(preferences);
</script>
<template>
<section>
<label><input v-model="hideCompleted" type="checkbox" /> 隐藏已完成</label>
<p>{{ description }}</p>
<button type="button" @click="preferences.toggleVisibility">切换</button>
</section>
</template>
从 src/views 导入用 ../stores/preferences,从 App.vue 导入则用 ./stores/preferences。
不要直接解构 state
const { hideCompleted } = preferences 会得到读取时的值。使用 storeToRefs 提取 state/getter,方法可以直接使用或解构。
生命周期与持久化
同一个 Pinia 实例中,调用同一个 store 会得到共享状态。刷新页面通常会重新初始化。需要保存偏好时,可以明确读写 localStorage,或采用合适的持久化插件。
localStorage 内容可能缺失、过期或被修改,读取时要验证。密码、后端密钥不能放在前端 store。认证方案另见登录与权限。
SSR 应为每个请求创建正确的应用和 Pinia 实例,避免模块级共享用户数据。
练习
在列表页和 about 页都显示 description,在一个页面切换后跳转另一个页面,确认偏好仍然一致。刷新后观察状态变化。
检查答案
页面跳转不销毁整个 Pinia 实例,所以状态保留。刷新重新创建应用,未加持久化时状态回到初始值是预期行为。
参考:Pinia 简介、Store 核心概念。