Vue进阶之状态管理,解锁项目开发超能力

一、概念

状态管理是指对应用程序中状态的管理。在软件领域,状态是指在某个特定时刻,应用程序的数据和行为表现。

以一个简单的购物网站为例,购物车中的商品列表、用户的登录状态等都是状态。状态管理主要涉及这些状态如何被存储、更新和在不同组件(如果是网页或软件界面的不同部分)之间共享。

在前端开发中,像React有Redux等状态管理库,Vue.js有Vuex。这些工具可以帮助开发者有效组织和控制应用中的状态,让状态的变化可以被预测,方便调试,并且在多人协作开发时也能更好地维护代码。

Pinia是一个专为Vue.js应用程序设计的状态管理库,用于替代Vuex。我们将用Pinia来讲解状态管理。

二、Pinia的优势

  1. 简洁的API:无需使用mutations,通过actions就能直接修改状态,且store定义简单。

2.良好的类型推断:对TypeScript项目友好,能自动推断类型。

  1. 与组合式API完美配合:在Vue.js 3的setup函数中使用方便。

  2. 支持插件扩展:可通过编写插件来定制功能。

  3. 直观的状态共享:便于跨组件共享和管理状态。

三、配置

与路由管理一样先创建一个脚手架,在将要存放的文件夹里打开终端(cmd),输入pnpm create vue输入文件名,这里我们创建一个Pinia的文件。在配置脚手架相关插件时,与他们不同,我们要引入Pinia用于状态管理。

与路由管理不同,Pinia主要文件多了一个叫stores的文件夹,stores文件夹中有一个counter.js的文件,里面自动生成了一个简单的计时器函数,我们接下来就使用该函数来实现页面的计数。

四、Pinia的使用

先简单的讲解一下已有代码

(1)counter.js

javascript 复制代码
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

javascript 复制代码
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

①我们先创建一个简单的框架

html 复制代码
<template>
  <div class="container">
 
  </div>
</template>
<script setup>
</script>

<style scoped>
</style>

我们主要在template和script标签进行修改,样式大家根据需要添加即可。

②我们在<template>的div中用h3标签来展示公用数据库中count和doublecount的值(通过插值语法({{}}两个花括号)绑定对应数据),再设置一个按钮,绑定v-on:click事件来调用CounterStore.increment 方法实现点击自增操作。

html 复制代码
<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 文件里定义的状态管理仓库中的数据和方法了。

html 复制代码
<script setup>
import { useCounterStore } from "./stores/counter.js";

const CounterStore = useCounterStore();
</script>

这样一个计数器就设计好了,我再添加一点样式(不添加样式也可以)

html 复制代码
<style scoped>
.container {
  width: 50%;
  height: 450px;
  background-color: pink;
}
</style>

在浏览器打开效果

count的值和doubleCount的值会随着点击的次数分别+1和x1。

这样我们也可以在该组件上再增加一个组件,这里我们在HelloWorld组件中再次引入一个计数功能。

我们可以将App.vue复制到HelloWorld.vue,只要简单的修改一下即可。

html 复制代码
<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组件

html 复制代码
<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实例,如下:

javascript 复制代码
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持久性"查看。

相关推荐
好_快19 分钟前
Lodash源码阅读-head
前端·javascript·源码阅读
好_快21 分钟前
Lodash源码阅读-last
前端·javascript·源码阅读
阿鲁冶夫21 分钟前
20250311
前端
WHOAMI_老猫1 小时前
XSS-LABS靶场通关讲解
前端·xss
要加油哦~1 小时前
前端 | 向后端传数据,判断问题所在的调试过程
前端·javascript·vue.js
中工钱袋3 小时前
Vue 中地址栏参数与 HTTP 请求参数的同步问题
前端·vue.js·http
一只月月鸟呀3 小时前
Vue 过滤器 filter(s) 的使用
javascript·vue.js·ecmascript
zzlyx993 小时前
设备管理系统功能与.NET+VUE(IVIEW)技术实现
前端·vue.js·view design
秋月华星5 小时前
【flutter】TextField输入框工具栏文本为英文解决(不用安装插件版本
前端·javascript·flutter
—Qeyser6 小时前
用Deepseek写一个 HTML 和 JavaScript 实现一个简单的飞机游戏
javascript·游戏·html