全局状态管理插件 Vuex 介绍及使用

Vuex 是一款专为 Vue.js 应用设计的状态管理模式,用于集中管理组件间的共享数据。它提供了单向数据流、State、Getter、Mutation、Action以及Module等核心概念,帮助开发者在复杂应用中保持数据的一致性。本文介绍了Vuex的基本概念、工作原理,并通过实例展示了如何在实际项目中使用Vuex。
摘要由CSDN通过智能技术生成

Vuex 是什么

简介

官方解释:Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。Vuex 也集成到 Vue 的官方调试工具 devtools extension,提供了诸如零配置的 time-travel 调试、状态快照导入导出等高级调试功能。

笔者个人理解,一句即可以概括: Vuex 是用于管理 Vue 应用跨组件数据的工具。

跨组件数据指的是,在 A、B、C 组件都需要用到的数据,比如购物车的数量,在很多页面是需要用到的。

Vuex 如何存储数据

说起这个还真有很多同学对 Vuex 的存储概念比较模糊,那么下面我们来分析一下 Vuex 和 localStorage、sessionStorage 在存储上的区别。

  • Vuex

Vuex 存储在浏览器内存,它采用的是集中式存储管理应用的所有组件的状态,在不刷新网页的情况下,状态会一直保持,一旦刷新网页,所有状态都将会重制。

  • sessionStorage

sessionStorage 是一种会话型存储,用于保存同一窗口或标签页的数据,数据保存在浏览器本地,在关闭窗口或标签页之后将会删除这些数据,这就是会话型存储,就跟人于人说话一样,人走了对话就结束了。

  • localStorage

localStorage 是一种持久性存储,与 sessionStorage 的功能近乎相似,但是在数据的存储时长上有所区别。它可以让数据一直存在于浏览器本地,除非你主动的 clear 数据,或者重装浏览器。

很多同学会认为既然 localStorage 存储时效这么强大,为什么不能用它去代替 Vuex 管理应用的数据呢?当然,在某些场景下,数据存在 localStorage 是比较合适的,像一些不需要变化的数据。但是在 Vue 单页应用开发中,两个组件 A 和 B 共用一份数据,B 若是能响应 A 对数据的改动,这种情况下 localStorage 和 sessionStorage 就显得比较乏力,毕竟 Vuex 有一整套高度兼容 Vue.js 开发模式的结构。

Vuex 核心概念

单向数据流

什么是单向数据流呢?它指的是通过一定的规则去改变数据,数据触发视图的更新,通过视图中的方法去触发数据的更新,形成一个闭环。如下图所示:

img

但事与愿违,复杂应用里会遇到多个组件共享同状态,不同视图的行为变更同一个状态等等问题,这时单向数据流就会被破坏。

Vuex 的出现就是为了解决这类复杂场景应用,那么我们在看看一张官方提供的流程图:

img

绿色虚线框内被 Vuex 加持,Vue 组件通过 Dispatch 关键字触发 Actions,再通过 Commit 调用 Mutation 里的方法修改 State 数据,Vue 组件若是有依赖 Store 里的数据,那么便会触发 Vue
组件的 Render 重绘,这就又形成了一个闭环。

State

顾名思义,所有状态都将被存放在 State 中,类似 Vue 组件中的 data 属性,只不过 State 是面向整个应用,而 data 针对的是单个组件。在 Vue 入口页构造 Vue 实例的时候引入 store 之后,可以在组件中通过
this.$store.state 拿到。

Getter

它类似于 Vue 组件中的 computed 计算属性,计算一些需要二次改造的数据。举个例子,我在 Vue 组件中通过 this.$store.state 拿到 State 中的某个数据,但是我需要对这个数据过滤,一个 filter
方法就能拿到过滤后的数据,但是我在很多地方都要使用这个 filter 过滤条件,那么我不断的去复制粘贴(CV 大法),或者将这个 filter 方法抽离到公用函数再引入组件,两种方法都很鸡肋。Getter 为我们解决了这个难题,你可以在
store 中定义 getter 属性,state 数据可作为参数被传入,代码大致如下:

const store = new Vuex.Store({
   
  state: {
   
    todos: [
      {
    id: 1, text: '...', done: true },
      {
    id: 2, text: '...', done: false },
    ],
  },
  getters: {
   
    doneTodos: (state) => {
   
      return state.todos.filter((todo) => todo.done);
    },
  },
});

在 Vue 组件中便可以通过如下方式进行访问:

this.$store.getters.doneTodos; // [{ id: 1, text: '...', done: true }]

Getter 也可以接收其他的 getters 作为第二个参数:

getters: {
   
  // ...
  doneTodosCount: (state, getters) => {
   
    return getters.doneTodos.length;
  };
}
// 使用
store.getters.doneTodosCount; // -> 1

可以通过 mapGetter 将 store 中的 getter 属性映射到局部计算属性内:

import {
    mapGetters } from 'vuex';

export default {
   
  // ...
  computed: {
   
    // 使用对象展开运算符将 getter 混入 computed 对象中
    ...mapGetters([
      'doneTodosCount',
      'anotherGetter',
      // ...
    ]),
  },
};

在 Vue 组件中便可以直接用 this.doneTodosCount 取到你想要的过滤后的数据。

Mutation

我们修改 State 状态,需要触发一些方法,这些方法就放在 mutations 属性中,mutations 属性中的方法接受 2 个参数,第一个参数是
state,内部包含所有状态值。第二个参数为提交载荷(Playload),也就是在外部通过 store.commit 方法触发 mutations 时额外带入的值。代码如下所示:

const store = new Vuex.Store({
   
  state: 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值