零基础Vue入门7——状态管理Pinia
本节重点:
- pinia是什么
- pinia怎么用
pinia是什么
vue中组件间的数据传递:
- app.config.globalProperties:能够被应用内所有组件实例访问到的全局属性的对象
- props:父传子用
- provide:父传后代用
想象下有咩有哪些数据存储是上述没法存的吗?一般随着项目越来越复杂,一个项目都是有多个菜单组成的,例如一个收费系统可以包含入网、客户资料管理、客户收费、组织机构管理、权限角色管理等模块。模块和模块之间(或者有的菜单和菜单之间)有些数据是共享的,例如用户信息、登录用户的权限信息等。这些内容是无法使用上述3块内容的。
Pinia 是Vue的专属状态管理库允许跨组件或页面共享状态。优点:
- 简单易用:API 设计简洁直观,学习成本低。
- 类型安全:在 TypeScript 项目中能提供良好的类型支持。
- 模块化设计:方便代码的组织和维护。
使用
安装和初始化
pnpm install pinia
// main.js
import { createApp } from 'vue';
import { createPinia } from 'pinia';
import App from './App.vue';const app = createApp(App);
const pinia = createPinia();app.use(pinia);
创建和使用
在项目的 src 目录下创建一个 stores 文件夹,用于存放所有的 Store 文件。在 stores 文件夹中创建一个 counter.ts文件。
这个文件结构优点想vue2 的选项式api的模式,定义好几个模块,什么内容放在什么下面即可。
// src/stores/counter.js
import { defineStore } from 'pinia';export const useCounterStore = defineStore('counter', {// 定义状态state: () => ({count: 0}),// 定义 getters,类似于计算属性getters: {doubleCount: (state) => state.count * 2},// 定义 actions,用于修改状态actions: {increment() {this.count++;}}
});
上述代码中:
- defineStore 是 Pinia 提供的一个函数,用于定义一个 Store,命名要求都以use开头store结尾。
- 'counter' 是 Store 的唯一 id,用于区分不同的 Store。
- state 是一个函数,返回一个对象,包含了 Store 的初始状态。
- getters 是一个对象,包含了一些计算属性,用于获取状态的派生值。
- actions 是一个对象,包含了一些方法,用于修改状态。
使用
<template><div><!--模板中就可以使用了 --><p>Count: {{ counterStore.count }}</p><p>Double Count: {{ counterStore.doubleCount }}</p><button @click="counterStore.increment">Increment</button></div>
</template><script setup>
// 引入了 useCounterStore 函数
import { useCounterStore } from '../stores/counter';// 调用 useCounterStore 函数获取 counter Store 的实例
const counterStore = useCounterStore();
</script>
访问其他store
// src/stores/counter.js
import { defineStore } from 'pinia';
import { useAuthStore } from './auth-store'export const useCounterStore = defineStore('counter', {// 定义状态state: () => ({count: 0,preferences: null,}),// 定义 getters,类似于计算属性getters: {doubleCount: (state) => state.count * 2},// 定义 actions,用于修改状态actions: {increment() {this.count++;},async fetchUserPreferences() {const auth = useAuthStore()if (auth.isAuthenticated) {this.preferences = await fetchPreferences()} else {throw new Error('User must be authenticated')}},}
});
响应式解构
从 Store 中解构出状态时,默认情况下会失去响应式。为了保持响应式,可以使用 storeToRefs 函数
<template><div><p>Count: {{ count }}</p><button @click="increment">Increment</button></div>
</template><script setup>
import { useCounterStore } from '../stores/counter';
import { storeToRefs } from 'pinia';const counterStore = useCounterStore();
const { count } = storeToRefs(counterStore);
const { increment } = counterStore;
</script>
项目中的最佳实践
模块化设计
将不同业务模块的状态分别存放在不同的 Store 文件中,例如用户信息存放在 user.js 中,商品信息存放在 product.js 中,这样可以提高代码的可维护性。
合理使用 getters 和 actions
getters:用于获取状态的派生值,避免在组件中重复计算。
actions:用于修改状态,将复杂的业务逻辑封装在 actions 中,使组件的代码更加简洁。
状态持久化
在实际项目中,有些状态需要持久化,比如用户的登录状态。可以使用 pinia-plugin-persistedstate 插件来实现状态的持久化
pnpm install pinia-plugin-persistedstate
// main.js
import { createApp } from 'vue';
import { createPinia } from 'pinia';
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate';
import App from './App.vue';const app = createApp(App);
const pinia = createPinia();
pinia.use(piniaPluginPersistedstate);app.use(pinia);
app.mount('#app');
然后在 Store 中配置持久化:
// src/stores/counter.js
import { defineStore } from 'pinia';
import { useAuthStore } from './auth-store'export const useCounterStore = defineStore('counter', {// 定义状态state: () => ({count: 0,preferences: null,}),// 定义 getters,类似于计算属性getters: {doubleCount: (state) => state.count * 2},// 定义 actions,用于修改状态actions: {increment() {this.count++;},async fetchUserPreferences() {const auth = useAuthStore()if (auth.isAuthenticated) {this.preferences = await fetchPreferences()} else {throw new Error('User must be authenticated')}},},// 配置持久化persist: true
});
继续下一节:零基础Vue入门7——状态管理Pinia-CSDN博客
若碰到其他的问题 可以私信我 一起探讨学习
如果对你有所帮助还请 点赞
收藏 谢谢~!
关注收藏博客 持续更新中,欢迎订阅专栏