一、概念
状态管理是指对应用程序中状态的管理。在软件领域,状态是指在某个特定时刻,应用程序的数据和行为表现。
以一个简单的购物网站为例,购物车中的商品列表、用户的登录状态等都是状态。状态管理主要涉及这些状态如何被存储、更新和在不同组件(如果是网页或软件界面的不同部分)之间共享。
在前端开发中,像React有Redux等状态管理库,Vue.js有Vuex。这些工具可以帮助开发者有效组织和控制应用中的状态,让状态的变化可以被预测,方便调试,并且在多人协作开发时也能更好地维护代码。
Pinia是一个专为Vue.js应用程序设计的状态管理库,用于替代Vuex。我们将用Pinia来讲解状态管理。
二、Pinia的优势
1. 简洁的API:无需使用mutations,通过actions就能直接修改状态,且store定义简单。
2. 良好的类型推断:对TypeScript项目友好,能自动推断类型。
3. 与组合式API完美配合:在Vue.js 3的setup函数中使用方便。
4. 支持插件扩展:可通过编写插件来定制功能。
5. 直观的状态共享:便于跨组件共享和管理状态。
三、配置
与路由管理一样先创建一个脚手架,在将要存放的文件夹里打开终端(cmd),输入pnpm create vue输入文件名,这里我们创建一个Pinia的文件。在配置脚手架相关插件时,与他们不同,我们要引入Pinia用于状态管理。
与路由管理不同,Pinia主要文件多了一个叫stores的文件夹,stores文件夹中有一个counter.js的文件,里面自动生成了一个简单的计时器函数,我们接下来就使用该函数来实现页面的计数。
四、Pinia的使用
先简单的讲解一下已有代码
(1)counter.js
import { ref, computed } from 'vue'
import { defineStore } from 'pinia'export const useCounterStore = defineStore('counter', () => {const count = ref(0)const doubleCount = computed(() => count.value * 2)function increment() {count.value++}return { count, doubleCount, increment }
})
①与前面一样,从vue中引入ref和computed;这里我们还要从Pinia中导入defineStore来构建状态管理的相关内容。
②通过defineStore定义一个名为“counter”的仓库,内部有一个响应式数据count初始值为0,一个计算属性doubleCount依赖count并范围两倍的值,还有一个increment方法用于自增count的值。
③将这几个属性和方法返回供外部使用,实现了一个简单的计数相关的状态管理逻辑
(2)main.js
import './assets/main.css'
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import App from './App.vue'
const app = createApp(App)
app.use(createPinia())
app.mount('#app')
①从 vue 库中导入 createApp 用于创建 Vue 应用实例,从 pinia 导入 createPinia 用于创建 pinia 实例来管理状态。
②通过 createApp 创建 App 应用实例,接着使用 app.use(createPinia()) 将 pinia 挂载到 Vue 应用上,使得整个应用可以使用 pinia 进行状态管理,最后将应用挂载到 #app 这个 DOM 节点上。
目前两个js文件不用进行修改就可以实现计数功能。
(3)App.vue
①我们先创建一个简单的框架
<template><div class="container"></div>
</template>
<script setup>
</script><style scoped>
</style>
我们主要在template和script标签进行修改,样式大家根据需要添加即可。
②我们在<template>的div中用h3标签来展示公用数据库中count和doublecount的值(通过插值语法({{}}两个花括号)绑定对应数据),再设置一个按钮,绑定v-on:click事件来调用CounterStore.increment 方法实现点击自增操作。
<template><div class="container"><h2>我是App.vue组件</h2><h3>Pinia公用数据库里面的count为:{{ CounterStore.count }}</h3><h3>Pinia公用数据库里面的doubleCount为:{{ CounterStore.doubleCount }}</h3><button v-on:click="CounterStore.increment">点我+1(调用的是公用方法)</button></div>
</template>
后续我还要引入另一个组件,所以这里用一个h2标签“我是App.vue”来区分
③从 "./stores/counter.js" (注意路径不要写错)中导入 useCounterStore 函数,然后调用它获取到 CounterStore,这样就能在模板中方便地访问和操作 Count.js 文件里定义的状态管理仓库中的数据和方法了。
<script setup>
import { useCounterStore } from "./stores/counter.js";const CounterStore = useCounterStore();
</script>
这样一个计数器就设计好了,我再添加一点样式(不添加样式也可以)
<style scoped>
.container {width: 50%;height: 450px;background-color: pink;
}
</style>
在浏览器打开效果
count的值和doubleCount的值会随着点击的次数分别+1和x1。
这样我们也可以在该组件上再增加一个组件,这里我们在HelloWorld组件中再次引入一个计数功能。
我们可以将App.vue复制到HelloWorld.vue,只要简单的修改一下即可。
<template><div class="container1"><h2>我是App.vue组件</h2><h3>Pinia公用数据库里面的count为:{{ CounterStore.count }}</h3><h3>Pinia公用数据库里面的doubleCount为:{{ CounterStore.doubleCount }}</h3><button v-on:click="CounterStore.increment">点我+1(调用的是公用方法)</button></div>
</template>
<script setup>
import { useCounterStore } from "../stores/counter.js";const CounterStore = useCounterStore();
</script><style scoped>
.container1 {width: 50%;height: 450px;background-color: rgb(213, 139, 151);
}
</style>
注意:路径不要写错。
App.vue要引用HelloWorld组件
<template><div class="container"><h2>我是App.vue组件</h2><h3>Pinia公用数据库里面的count为:{{ CounterStore.count }}</h3><h3>Pinia公用数据库里面的doubleCount为:{{ CounterStore.doubleCount }}</h3><button v-on:click="CounterStore.increment">点我+1(调用的是公用方法)</button><HelloWorld/></div>
</template>
<script setup>
import HelloWorld from "./components/HelloWorld.vue";
import { useCounterStore } from "./stores/counter.js";const CounterStore = useCounterStore();
</script><style scoped>
.container {width: 50%;height: 450px;background-color: pink;
}
</style>
这样就可以了
五、Pinia的持久性
在现代的Vue.js应用开发中,Pinia作为状态管理库已经广受欢迎。其中,数据的持久性是一个非常重要的特性,它能确保应用在页面刷新或重新打开后,依然能够恢复之前的状态。
六、为什么需要Pinia的持久性
在许多应用场景中,用户不希望自己辛苦操作得到的状态(如购物车中的商品列表、用户偏好设置等)因为页面的刷新就丢失。例如,在一个电商应用里,用户已经挑选了好几件商品放入购物车,若每次刷新页面购物车就被清空,这会极大地影响用户体验。Pinia的持久性功能就很好地解决了这个问题。
七、持久性的基本方法
1、安装
Pinia提供了插件机制来实现数据的持久存储。一个简单的实现方式是通过pinia-plugin-persistedstate插件。我们在终端输入“pnpm i pinia-plugin-persistedstate”即可。
2、将插件添加到你的Pinia实例中
在main.js(或main.ts)文件中引入Pinia和插件。首先要创建Pinia实例,如下:
import { createApp } from 'vue';
import { createPinia } from 'pinia';
import piniaPluginPersistedstate from 'pinia - plugin - persistedstate';
const app = createApp(App);
const pinia = createPinia();
// 使用插件
pinia.use(piniaPluginPersistedstate);
app.use(pinia);
这样,Pinia中的所有状态都会默认被持久化存储。如果只想持久化部分状态,可以在store模块中进行配置。
这样Pinia的持久性就设置好了,详细安装教程请点击“Pinia持久性”查看。