vue 全局状态管理(简单的store模式、使用Pinia)

这篇具有很好参考价值的文章主要介绍了vue 全局状态管理(简单的store模式、使用Pinia)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

为什么使用状态管理

多个组件可能会依赖同一个状态时,我们有必要抽取出组件内的共同状态集中统一管理,存放在一个全局单例中,这样任何位置上的组件都可以访问其中的状态或触发动作

简单的store模式

通过自定义一个store模式实现全局的状态管理,实例如下
有两个组件a、b共享store和store2两个状态,我们将其抽离在一个全局单例中,代码如下:

import { reactive } from "vue";
export const store = reactive({
  count: 0
});
export const store2 = {
  count: 0
};

a组件中:

<script setup>
import { store, store2 } from "./store.js";
console.log(store, store2);
</script>

<template>
  <div @click="store.count++">From A: {{ store.count }}</div>
</template>

b组件中:

<script setup>
import { store, store2 } from "./store.js";
console.log(store, store2);
</script>

<template>
  <div @click="store2.count++">From B: {{ store.count }}</div>
</template>

这样,a、b组件共享了store和store2两个值,在一个组件中对值进行更新,在其他组件中对应的值也会发生改变。

同时关闭a、b组件后,值依然保存,重新加载两个组件,原来的状态值存在。

重新刷新后,store和store2会变为初始值,如果需要做持久化,则需要再使用localstorage等进行存储。

服务器渲染(SSR)

这种简单store模式下,可能会出现跨请求状态污染。

在 SSR 环境下,应用模块通常只在服务器启动时初始化一次。同一个应用模块会在多个服务器请求之间被复用,而我们的单例状态对象也一样。如果我们用单个用户特定的数据对共享的单例状态进行修改,那么这个状态可能会意外地泄露给另一个用户的请求。我们把这种情况称为跨请求状态污染

pinia

简介

pinia在设计时考虑了ssr,参考这里(服务端渲染 (SSR) | Pinia (vuejs.org))

Vuex是一个专为 Vue.js 应用程序开发的状态管理模式 + 库。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。

Pinia 最初正是为了探索 Vuex 的下一个版本而开发的,整合了vue核心团队关于 Vuex 5 的许多想法。

相比于 Vuex,Pinia 提供了更简洁直接的 API,并提供了组合式风格的 API,最重要的是,在使用 TypeScript 时它提供了更完善的类型推导。

示例

1. 定义一个index.ts文件

import { createPinia } from "pinia";
import piniaPluginPersistedstate from "pinia-plugin-persistedstate";

// pinia persist
const pinia = createPinia();
pinia.use(piniaPluginPersistedstate);

export default pinia;

直接通过引入pinia-plugin-persistedstate插件来实现数据的持久化,默认进行localstorage方式持久化存储(pinia只是状态管理库,默认是不会进行数据持久化的

当然,有很多的存储方法,比如vueuse的 useLocalStorage方法,但是为什么需要用到pinia-plugin-persistedstate呢,官方文档给出了理由:

pinia-plugin-persistedstate 旨在通过一致的 API 为每个人和每个项目中的 Pinia Store 提供持久化存储。如果你希望保存一个完整的 Store,或者需要细粒化配置 storage 和序列化的方式,该插件都为你提供了相应的功能,并且可以在你想要持久化的 Store 上使用相同的配置。

2. 在main.ts中引入

import pinia from "@/stores";
import { createApp } from "vue";
import App from "./App.vue";
const app = createApp(App);
app.use(pinia).mount("#app");

通过app.use实现插件全局注册以及初始化和配置,即使得全局的pinia都使用了piniaPluginPersistedstate插件

3. 定义

在/stores/modules/user文件,可以直接通过defineStore方法进行定义,状态存在state中。

actions中是对state的一些操作和方法,其他组件通过这些方法操作state,保证状态以一种可预测的方式发生变化。

getters中是获取state的一些方法,在这些方法中可以对state做一些预处理和变化再传递给调用的组件

import { defineStore } from "pinia";
import { UserState } from "@/stores/interface";
import piniaPersistConfig from "@/config/piniaPersist";

export const useUserStore = defineStore({
  id: "user",
  state: (): UserState => ({
    token: "",
    userInfo: { name: "cc" }
  }),
  getters: {},
  actions: {
    // Set Token
    setToken(token: string) {
      this.token = token;
    },
    // Set setUserInfo
    setUserInfo(userInfo: UserState["userInfo"]) {
      this.userInfo = userInfo;
    }
  },
  persist: piniaPersistConfig("user")
});

persist则是引入了piniaPluginPersistedstate持久化后的一些可配置信息

/config/piniaPersist内容如下:

import { PersistedStateOptions } from "pinia-plugin-persistedstate";

/**
 * @description pinia 持久化参数配置
 * @param {String} key 存储到持久化的 name
 * @param {Array} paths 需要持久化的 state name
 * @return persist
 * */
const piniaPersistConfig = (key: string, paths?: string[]) => {
  const persist: PersistedStateOptions = {
    key,
    storage: localStorage,
    // storage: sessionStorage,
    paths
  };
  return persist;
};

export default piniaPersistConfig;

paths用于指定 state 中哪些数据需要被持久化。[] 表示不持久化任何状态,undefinednull 表示持久化整个 state。

更多配置信息可以参考官方文档prazdevs.github.io/pinia-plugin-persistedstate/zh/guide/config.html

4. 使用

import { useUserStore } from "@/stores/modules/user";
const userStore = useUserStore();
router.beforeEach( (to, from, next) => {
    if (userStore.token) return next(from.fullPath);
}

通过const userStore = useUserStore();引入userStore,全局token来判断当前登录状态

storeToRefs

解构赋值后的变量会丧失响应性,使用storeToRefs方法可以使变量重新获得响应性。
注意这里的变量应该指的是基本数据类型,如果是对象,则会保留响应性。

例如:定义如下store

export const useUserStore = defineStore({
  id: "user",
  state: (): UserState => ({
    token: "",
    userInfo: { name: "Geeker" }
  }),
  getters: {
    getUserInfo(state) {
      return state.userInfo;
    }
  },
  actions: {
    // Set Token
    setToken(token: string) {
      this.token = token;
    },
    // Set setUserInfo
    setUserInfo(userInfo: UserState["userInfo"]) {
      this.userInfo = userInfo;
    },
    setName(name: string) {
      this.userInfo.name = name;
    }
  },
  persist: piniaPersistConfig("user")
});

在其他组件中引入

<script setup lang="ts">
import { computed } from "vue";
import { storeToRefs } from "pinia";
import { useUserStore } from "@/stores/modules/user";

const userStore = useUserStore();
const username = computed(() => userStore.userInfo.name);
const { userInfo } = userStore;
console.log(userInfo);

const { token } = storeToRefs(userStore);
console.log(token);
const changeToken = () => {
  userStore.setToken("123" + Math.random());
  console.log(token);
};
</script>

<template>
 <span class="username">{{ username }}</span>
 <span @click="userStore.setName('456')">{{ userStore.getUserInfo.name }}</span>
 <span @click="userInfo.name = 'zcc'" class="username">{{ userInfo.name }}</span>
 <span @click="changeToken">{{ token }}</span>
</template>

结果如图,此时token和userInfo都是具有响应性的,使用changeToken函数后store中的token和解构的token都会发生变化
vue 全局状态管理(简单的store模式、使用Pinia),vue,vue.js,前端,javascript
但是如果将storeToRefs去掉

<script setup lang="ts">
import { computed } from "vue";

import { useUserStore } from "@/stores/modules/user";

const userStore = useUserStore();
const username = computed(() => userStore.userInfo.name);
const { userInfo } = userStore;
console.log(userInfo);

const { token } = userStore;
console.log(token);
const changeToken = () => {
  userStore.setToken("123" + Math.random());
    console.log("失去响应的", token);
  console.log("userStore.token", userStore.token);
};
</script>

结果如图,token将丧失响应性
vue 全局状态管理(简单的store模式、使用Pinia),vue,vue.js,前端,javascript
此时调用changeToken函数,只有userStore.token会变化,解构的token不会变化
vue 全局状态管理(简单的store模式、使用Pinia),vue,vue.js,前端,javascript
但是对于userInfo来说,无论是修改store中的name——userStore.setName(‘456’)",还是直接修改解构的userInfo——userInfo.name = ‘zcc’,上述代码中的三项不同方式获取的name都会同时发生改变。文章来源地址https://www.toymoban.com/news/detail-637176.html

到了这里,关于vue 全局状态管理(简单的store模式、使用Pinia)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • 微信小程序开发(第五期):npm包的使用、Vant Weapp 组件库的使用 && API Promise优化 、全局状态管理 && store 、分包、分包预下载 && 自定义配置tabBar

    微信小程序开发(第五期):npm包的使用、Vant Weapp 组件库的使用 && API Promise优化 、全局状态管理 && store 、分包、分包预下载 && 自定义配置tabBar

    LiuJInTao:2024年4月6日 一、小程序对 npm 包的限制 二、Vant Weapp 组件库 1. 什么是 Vant Weapp 官网文档地址 2. Vant Weapp 组件库的安装 注意点: 我们最新版本的微信开发者工具是不是没有勾选npm的,默认系统内部自动勾选。 步骤一 通过 npm 安装 使用npm构建前,请先阅读微信官方的

    2024年04月27日
    浏览(7)
  • Vue3 store+pinia 基本使用

    pinia是一个 状态管理的库 ,用于 跨组件、页面进行状态共享 (这和Vuex、Redux一样),用起来像组合式API Pinia和Vuex有什么区别 1、PInia的最初是为了探索Vuex的下一次迭代会是什么样子,结合了Vuex核心团队讨论中的许多想法; 2、最终,团队意识到Pinia已经实现了Vuex5中大部分内

    2024年02月07日
    浏览(12)
  • vue3中状态管理库pinia的安装和使用方法介绍及和vuex的区别

    Pinia 与 Vuex 一样,是作为 Vue 的“状态存储库”,用来实现 跨页面/组件 形式的数据状态共享。它允许你跨组件或页面共享状态。如果你熟悉组合式 API 的话,你可能会认为可以通过一行简单的 export const state = reactive({}) 来共享一个全局状态。 当该数据、方法在很多地方都需要

    2024年01月20日
    浏览(7)
  • Vue——状态管理库Pinia

    Vue——状态管理库Pinia

    写在前面 :本文参考小满大牛的pinia专栏 Vuex 和 Pinia 均是 Vue.js 的状态管理库,它们为 Vue 应用程序提供了一种集中式的、可预测的状态管理解决方案。 Vuex 是 Vue.js 官方推荐的状态管理库之一。它的核心概念包括 state、mutation、action 和 getter。其中,state 代表应用程序的状态

    2024年02月07日
    浏览(10)
  • Vue状态管理库-Pinia

    Vue状态管理库-Pinia

    Pinia 是 Vue 的专属状态管理库,它允许支持跨组件或页面共享状态,即共享数据,他的初始设计目的是设计一个支持组合式API的 Vue 状态管理库(因为vue3一个很大的改变就是组合式API),当然这并不是说Pinia只支持vue3,他是同时支持vue2和vue3的, 本文倾向于拥抱Vue3,所以代码语

    2024年02月22日
    浏览(8)
  • 【Vue全家桶】Pinia状态管理

    【Vue全家桶】Pinia状态管理

    🤗这里是前端程序员小张! 🌻人海茫茫,感谢这一秒你看到这里。希望我的文章对你的有所帮助! 🌟愿你在未来的日子,保持热爱,奔赴山海! Pinia开始于大概2019年,其目的是设计一个拥有 组合式 API 的 Vue 状态管理库 目前同时兼容Vue2、Vue3,也并不要求你使用Compositio

    2023年04月09日
    浏览(38)
  • Vue--》探索Pinia:Vue状态管理的未来

    Vue--》探索Pinia:Vue状态管理的未来

    目录 Pinia的讲解与使用 Pinia的安装与使用 store数据操作 解构store数据

    2024年02月05日
    浏览(5)
  • vue3学习-Pinia状态管理

    定义一个Store 这个 name ,也称为 id ,是必要的,Pinia 使用它来将 store 连接到 devtools。 将返回的函数命名为 use… 是跨可组合项的约定,以使其符合你的使用习惯。 使用 store 一旦 store 被实例化,你就可以直接在 store 上访问 state 、 getters 和 actions 中定义的任何属性 store 是一

    2024年02月14日
    浏览(6)
  • Vue | Vue.js 全家桶 Pinia状态管理

    Vue | Vue.js 全家桶 Pinia状态管理

    🖥️ Vue .js专栏:Node.js Vue.js 全家桶 Pinia状态管理 🧑‍💼 个人简介:一个不甘平庸的平凡人🍬 ✨ 个人主页:CoderHing的个人主页 🍀 格言: ☀️ 路漫漫其修远兮,吾将上下而求索☀️ 👉 你的一键三连是我更新的最大动力❤️ 目录 一、Pinia和Vuex的对比 什么是Pinia呢? Pina和

    2024年01月16日
    浏览(41)
  • Vue最新状态管理工具Pinia——彻底搞懂Pinia是什么

    Vue最新状态管理工具Pinia——彻底搞懂Pinia是什么

    知识专栏 专栏链接 Vuex知识专栏 https://blog.csdn.net/xsl_hr/category_12158336.html?spm=1001.2014.3001.5482 Vuex官方文档 https://vuex.vuejs.org/zh/ Pinia官方文档 https://pinia.web3doc.top/ 最近在 前端的深入学习过程 中,接触了与 状态管理 相关的内容,涉及到 与vue2适配的vuex 和 与vue3适配的pinia ,因此

    2024年02月03日
    浏览(19)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包