Pinia,Vue最好的存储库!谁赞成?谁反对?

1. 状态管理

在程序开发过程中,有很多页面需要共享一些数据,这些数据需要我们保存在程序的某一个地方。管理这些数据的过程就叫做状态管理。

2. Pinia

Pinia 是一个专为 Vue 设计的状态管理工具,它比 Vuex 学起来更简单,而且同时支持 Vue2 和 Vue3 语法。

中文官网:

css 复制代码
https://pinia.web3doc.top/

3. 安装配置

命令行输入:

css 复制代码
npm install pinia

在 main.js 文件中配置 Pinia

css 复制代码
import { createApp } from 'vue'
import App from './App.vue'
const pinia = createPinia()
app.use(pinia).mount("#app")

4. 创建 Store

Pinia 中的 Store 主要包含三部分:state、getters、actions,创建方式同时支持 Vue2 和 Vue3 语法。

  • Vue2 选项式API
  • Vue3 组合式API

这里我个人更推荐使用选项式 API,因为更直观。

4.1 id

在 Pinia 中,每一个 Store 都要有唯一的名称,或者唯一的id。

命名 id 的方式有 2 种:

第1种:将 id 作为 defineStore 方法的参数

第2种:在 defineStore 方法体内定义 id

4.2 State

State 其实就是我们需要存储的数据

css 复制代码
  state: () => ({
    count: 1,
    name:"知否君",
    menuList:[]
  }),

4.3 Getter

Getter 是计算过后的数据

css 复制代码
  getters: {
    doubleCount() {
      return this.count * 2;
    },
  },

4.4 Action

Action 就是操作数据的一些方法

css 复制代码
actions: {
  // 自增操作
  increment() {
    this.count++;
  },
},

在 Pinia中,如果要处理异步请求,我们需要采用 async-await 的方式:

css 复制代码
  actions: {
    // 获取菜单列表
    async getMenuList() {
      const { data } = await axios.get('/api/menuList')
      this.menuList = data
    }
  },

5. Pinia 案例

5.1 案例一:计数

1.新建 counter.js

2.导入 counter

css 复制代码
import { useCounterStore } from "@/store/counter";
const useCounter = useCounterStore();

3.state 和方法

css 复制代码
<template>
  <el-card style="margin: 20px">
    <template #header>
      <span style="font-weight: bold">新一代Vue存储库Pinia</span>
    </template>
    <!-- 计数操作 -->
    <p>数值:{{ useCounter.count }}</p>
    <p>2倍数值:{{ useCounter.doubleCount }}</p>
    <el-button type="primary" @click="useCounter.increment">点击+1</el-button>
    <el-button type="primary" @click="useCounter.$reset()">重置</el-button>
  </el-card>
</template>

4.完整代码

css 复制代码
<template>
  <el-card style="margin: 20px">
    <template #header>
      <span style="font-weight: bold">新一代Vue存储库Pinia</span>
    </template>
    <!-- 计数操作 -->
    <p>数值:{{ useCounter.count }}</p>
    <p>2倍数值:{{ useCounter.doubleCount }}</p>
    <el-button type="primary" @click="useCounter.increment">点击+1</el-button>
    <el-button type="primary" @click="useCounter.$reset()">重置</el-button>
  </el-card>
</template>
<script setup>
import { useCounterStore } from "@/store/counter";
const useCounter = useCounterStore();
</script>

注:useCounter.$reset() 方法可以重置 Pinia 中的数值,但是前提 store 语法必须是 Vue2 选项式 API ,不然会失效。

5.效果

6.解构

注: 直接从 store 中解构的数据不能实时响应,要想保持实时响应,必须用 storeToRefs() 方法包裹。

css 复制代码
<template>
  <el-card style="margin: 20px">
    <template #header>
      <span style="font-weight: bold">新一代Vue存储库Pinia</span>
    </template>
    <!-- 计数操作 -->
    <p>数值:{{ count }}</p>
    <p>2倍数值:{{ doubleCount }}</p>
    <el-button type="primary" @click="useCounter.increment">点击+1</el-button>
    <el-button type="primary" @click="useCounter.$reset()">重置</el-button>
  </el-card>
</template>
<script setup>
import { useCounterStore } from "@/store/counter";
import { storeToRefs } from "pinia";
const useCounter = useCounterStore();
const { count, doubleCount } = storeToRefs(useCounter);
</script>

5.2 案例二:添加用户

1.新建 user.js

2.获取 state 和调用方法

css 复制代码
<template>
  <el-card style="margin: 20px">
    <template #header>
      <span style="font-weight: bold">新一代Vue存储库Pinia</span>
    </template>
    <!-- 添加用户 -->
    <el-divider>添加用户</el-divider>
    <el-form ref="userFormRef" :model="userForm" label-width="120px" style="width: 40%">
      <el-form-item label="姓名:" prop="name">
        <el-input v-model="userForm.name" placeholder="请输入姓名" />
      </el-form-item>
      <el-form-item label="年龄:" prop="age">
        <el-input-number
          style="width: 100%"
          :min="18"
          controls-position="right"
          v-model="userForm.age"
        />
      </el-form-item>
      <el-form-item label="学校:" prop="school">
        <el-input v-model="userForm.school" placeholder="请输入学校" />
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="useUser.addUser(userForm)">添加</el-button>
        <el-button @click="useUser.$reset()">重置Pinia数据</el-button>
        <el-button @click="useUser.deleteUser">删除所有</el-button>
      </el-form-item>
    </el-form>
    <!-- 用户列表 -->
    <el-divider>用户列表</el-divider>
    <div v-if="userList.length > 0">
      <el-tag style="margin: 0px 10px" v-for="users in userList"
        >{{ users.name }}:{{ users.age }}:{{ users.school }}</el-tag
      >
    </div>
  </el-card>
</template>
<script setup>
import { useUserStore } from "@/store/user";
import { reactive, ref } from "vue";
import { storeToRefs } from "pinia";
const useUser = useUserStore();
const { userList } = storeToRefs(useUser);
// userForm
const userForm = reactive({ name: "", age: "", school: "" });
</script>

3.效果

6. 持久化

在使用 Pinia 的时,我们会发现刷新页面之后,数据又重置了,这时候我们可以使用 Pinia 的 Persist 插件将数据持久化到本地。

6.1 安装 pinia-plugin-persist 插件

css 复制代码
npm install pinia-plugin-persist

6.2 在 main.js 配置 pinia-plugin-persist

css 复制代码
import App from './App.vue'
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import piniaPluginPersist from 'pinia-plugin-persist'
const app = createApp(App)
const pinia = createPinia()
pinia.use(piniaPluginPersist)
app.use(pinia)
app.mount("#app")

6.3 使用持久化插件

在 store 添加

css 复制代码
// 开启持久化
 persist: { enabled: true }

我们发现该插件默认是将数据存储到 sessionStorage 中,key 值默认是 store 的 id 值,value 默认存储该 Store 的所有 state。

我们还可以自定义存储的 key 、持久化引擎和要持久化哪些数据:

相关推荐
Lank_M几秒前
关键帧从1秒拉到10秒,录屏小87.3%,摄像头小10.8%
前端
补码缩写2 分钟前
用 ffprobe 拆录屏,八成字节在 29 个关键帧上
前端
百思不得小李4 分钟前
一个复杂的动态表单是如何实现的
前端·设计模式
陈随易18 分钟前
Cmder 停更 17 个月,2.0 支持 Windows Terminal
前端·后端·程序员
风骏时光牛马29 分钟前
前沿视界
前端
kyriewen34 分钟前
我扫了 814 个依赖,97 个还敢要 Node 10
前端·javascript·程序员
陈随易1 小时前
3000 万人在用的翻译插件,重写一遍就是一门生意
前端·后端·程序员
IT_陈寒1 小时前
Vue的这个响应式陷阱,差点让我加班到天亮
前端·人工智能·后端
Flynt2 小时前
别写拖拽行为,只声明"能拖到哪":UIST 最佳论文的拖拽方案我实测了
前端·svg·preact
Moment3 小时前
代码都能让 Agent 写了,我们为什么还要学前端?
前端·后端·面试