Vuex 核心揭秘:打造高效前端状态库

引言

Vue.js 是一个流行的 JavaScript 框架,以其简洁的设计和易用的特性赢得了开发者的青睐。它允许开发者通过声明式的方式编写前端代码,从而提高开发效率。

Vuex 是 Vue.js 的官方状态管理库,它为 Vue 应用提供了一个中心化存储,使得所有组件都能够访问和更新共享状态。这对于大型应用来说尤为重要,因为它可以避免状态混乱和难以维护的问题。

为什么需要 Vuex?

随着应用规模的扩大,组件之间的状态管理会变得越来越复杂。Vuex 提供了一套完整的解决方案,通过集中管理状态,使得状态的变化可预测、可追踪,从而提高了应用的可维护性。

作者本人学这一块知识点的时候倍感抽象,于是想写一篇博客给正在迷惑的朋友们

vuex简介

Vuex 的各个核心概念在 Vue 应用程序中都有对应的类似概念,下面是对应关系的一个简单说明:

  1. 状态(State)

    • 类似于 Vue 组件的 data 属性,用于存储组件的响应式数据。在 Vuex 中,state 用于存储整个应用的全局状态。
  2. Getters

    • 类似于 Vue 组件的 computed 计算属性,它们用于从其他数据派生出新的数据。在 Vuex 中,getters 用于从 state 中派生出一些状态,这些状态可以根据 state 的变化而缓存或重新计算。
  3. Mutations

    • 类似于 Vue 组件的 methods 中的方法,用于改变组件的 data。在 Vuex 中,mutations 用于改变 state 的状态,它们必须是同步的,以确保状态的改变是可追踪和可预测的。
  4. Actions

    • 类似于 Vue 组件的 methods 中的方法,但是用于处理异步操作。在 Vuex 中,actions 用于提交 mutations,而不是直接改变状态。actions 可以包含任何异步操作,如 API 请求。
  5. Modules

    • 类似于 Vue 组件的 components,它们允许你将一个大的组件拆分成多个小的、可复用的组件。在 Vuex 中,modules 允许你将一个大的 store 拆分成多个小的、可管理的模块,每个模块都有自己的 statemutationsactionsgetters

安装和配置 Vuex

首先,你得通过 npm 或者 yarn 把 Vuex 安装到你的项目里。打开终端,敲入下面的命令之一:

npm install vuex --save
# 或者
yarn add vuex

安装完毕后,下一步是创建一个 Vuex 的 store。这个 store 就像是你应用状态的大脑,它知道所有的事情,比如你的数据是什么,数据怎么变化,等等。创建 store 的代码通常放在一个叫 store.js 的文件里。

// 引入 Vue 和 Vuex
import Vue from 'vue';
import Vuex from 'vuex';

// 告诉 Vue 使用 Vuex
Vue.use(Vuex);

// 创建一个新的 Vuex store 实例
const store = new Vuex.Store({
  // 在 state 对象里定义你的应用状态
  state: {
    count: 0 // 假设我们有一个计数器
  },
  // mutations 是用来修改状态的地方
  mutations: {
    increment(state) {
      state.count++; // 每次调用这个 mutation,计数器就加一
    }
  },
  // actions 是用来提交 mutations 的,可以包含异步操作
  actions: {
    increment(context) {
      context.commit('increment'); // 这个 action 提交了 increment mutation
    }
  },
  // getters 是用来从状态派生出其他状态的方法
  getters: {
    getCount: state => state.count // 这个 getter 返回计数器的当前值
  }
});

// 把 store 导出,这样其他组件就能用到它了
export default store;

最后一步是在你的 Vue 应用程序里使用这个 store。在你的主文件,比如 main.jsindex.js,你需要做的是导入这个 store,并且在创建 Vue 实例的时候把它加进去。

import Vue from 'vue';
import App from './App.vue'; // 这是你的根组件
import store from './store'; // 导入我们刚刚创建的 store

// 创建 Vue 实例,把 store 作为配置的一部分
new Vue({
  store, // 这样一来,store 就可以在整个应用中使用啦
  render: h => h(App)
}).$mount('#app');

扩展(当项目比较大时)

在 Vuex 中,如果你的应用状态变得复杂,你可以通过创建模块(modules)来划分子状态管理。这样做可以让你的 store 更加模块化和可维护。下面是如何操作的步骤:

1. 创建主 store 文件(index.js

首先,创建一个主 store 文件(通常是 index.js),在这个文件中,你将导入并组合所有的模块。

请注意,记得导入分模块

import user from './modules/user';

import Vue from 'vue';
import Vuex from 'vuex';
import user from './modules/user';

Vue.use(Vuex);

export default new Vuex.Store({
  modules: {
    user
  }
});
2. 创建用户模块(modules/user.js

然后,创建一个用户模块(modules/user.js),在这个文件中,你将定义用户相关的 state、mutations、actions 和 getters。

const state = {
  userInfo: {}
};

const mutations = {
  SET_USER_INFO(state, userInfo) {
    state.userInfo = userInfo;
  }
};

const actions = {
  setUser({ commit }, userInfo) {
    commit('SET_USER_INFO', userInfo);
  }
};

const getters = {
  userInfo: state => state.userInfo
};

export default {
  namespaced: true,
  state,
  mutations,
  actions,
  getters
};
3. 在组件中使用模块

在你的 Vue 组件中,你可以通过 this.$store 访问主 store,并通过模块的名称空间来访问模块内的 state、mutations、actions 和 getters。

例如,在组件中设置用户信息:

javascript 复制代码
this.$store.dispatch('user/setUser', { name: 'John Doe', age: 30 });

/*这里,我们调用了 dispatch 方法,这是 Vuex store 的一个方法,用来触发一个 action。Action 是一个函数,它可以包含异步操作,比如从服务器获取数据或者延迟执行代码。

我们传给 dispatch 方法的第一个参数 'user/setUser' 是 action 的路径。因为我们使用了模块,所以这个路径包含了模块的名称 'user' 和 action 的名称 'setUser'。这样,Vuex 可以找到正确的 action 并执行它。

第二个参数 { name: 'John Doe', age: 30 } 是一个载荷(payload),它是一个对象,包含了我们想要传递给 action 的数据。在这个例子中,我们传递了一个包含用户名字和年龄的对象。

当 dispatch 方法被调用时,Vuex 会查找名为 setUser 的 action,并执行它。在 action 内部,我们可以执行任何我们想要的操作,比如异步请求或者复杂的逻辑,然后当我们准备好了的时候,我们可以提交一个 mutation 来改变 store 中的状态。*/

获取用户信息:

javascript 复制代码
console.log(this.$store.getters['user/userInfo']);
/*
这里,我们使用了 console.log 来打印出某个值。我们想要打印的是 this.$store.getters['user/userInfo']。

this.$store:这是访问 Vuex store 的方式,$store 是 Vue 实例上的一个属性,它在 Vue 实例中注入了 Vuex store。
getters:这是 store 上的一个属性,包含了所有定义的 getter 函数。
'user/userInfo':这是 getter 的路径,由于我们使用了模块,所以需要加上模块的名称空间 'user/' 作为前缀。userInfo 是在用户模块中定义的一个 getter。
*/
注意事项
  • namespaced: true:这个选项使得模块内部的 actions、mutations 和 getters 都被限定在模块的名称空间内。这样,你在组件中使用这些功能时,需要加上模块名称作为前缀。
  • 模块的状态是嵌套的,所以你在主 store 的 state 中可以通过模块名称来访问子状态,例如 this.$store.state.user.userInfo

扩展:进一步解释 Vuex 中 this.$store 的常用方法

  1. this.$store.state

    • this.$store.state 是访问 Vuex store 中状态(state)的地方。状态是响应式的,直接反映了应用的当前数据。
    • 例如,如果你想要获取 store 中的计数器值,你可以这样写:console.log(this.$store.state.count)
  2. this.$store.getters

    • this.$store.getters 是访问 Vuex store 中通过 getters 派生出来的状态。Getters 可以对 state 进行计算和加工。
    • 例如,如果你有一个名为 doubleCount 的 getter,你可以这样访问它:console.log(this.$store.getters.doubleCount)
  3. this.$store.commit('mutationName', payload)

    • this.$store.commit 是提交 mutation 来更改 store 的状态。Mutations 是同步函数。
    • 例如,如果你有一个名为 increment 的 mutation,你可以这样提交它:this.$store.commit('increment', { amount: 10 })
  4. this.$store.dispatch('actionName', payload)

    • this.$store.dispatch 是分派 action,Action 可以包含异步操作,并且可以触发多个 mutations。
    • 例如,如果你有一个名为 fetchUser 的 action,你可以这样分派它:this.$store.dispatch('fetchUser', { userId: 1 })
  5. this.$store.watch(fn, callback, options)

    • this.$store.watch 是观察 Vuex store 中的某个状态或 getter,当状态变化时执行回调函数。
    • 例如,如果你想要观察 count 状态的变化,你可以这样写:this.$store.watch((state) => state.count, (newCount, oldCount) => { console.log(Count changed from${oldCount} to ${newCount}); })

总结

  • Vuex 简介:Vuex 是 Vue.js 的官方状态管理库,提供了一个中心化存储来管理应用状态,有助于大型应用的状态管理。
  • 核心概念:Vuex 的核心概念包括 State(状态)、Getters(派生状态)、Mutations(同步更改状态)、Actions(异步操作)和 Modules(状态管理模块)。
  • 安装和配置:通过 npm 或 yarn 安装 Vuex,并在主文件中创建一个 Vuex Store,然后将 Store 注入到 Vue 实例中。
  • 模块化:如果你的应用状态变得复杂,可以通过创建模块来划分状态管理,使 Store 更加模块化和可维护。
  • 常用方法:使用 this.𝑠𝑡𝑜𝑟𝑒.𝑠𝑡𝑎𝑡𝑒访问状态,𝑡ℎ𝑖𝑠.store.state访问状态,this.store.getters 访问派生状态,this.𝑠𝑡𝑜𝑟𝑒.𝑐𝑜𝑚𝑚𝑖𝑡提交状态更改,𝑡ℎ𝑖𝑠.store.commit提交状态更改,this.store.dispatch 分派异步操作,this.$store.watch 观察状态变化。
相关推荐
_斯洛伐克44 分钟前
下降npm版本
前端·vue.js
苏十八2 小时前
前端进阶:Vue.js
前端·javascript·vue.js·前端框架·npm·node.js·ecmascript
st紫月2 小时前
用MySQL+node+vue做一个学生信息管理系统(四):制作增加、删除、修改的组件和对应的路由
前端·vue.js·mysql
乐容3 小时前
vue3使用pinia中的actions,需要调用接口的话
前端·javascript·vue.js
似水明俊德3 小时前
ASP.NET Core Blazor 5:Blazor表单和数据
java·前端·javascript·html·asp.net
至天4 小时前
UniApp 中 Web/H5 正确使用反向代理解决跨域问题
前端·uni-app·vue3·vue2·vite·反向代理
与墨学长4 小时前
Rust破界:前端革新与Vite重构的深度透视(中)
开发语言·前端·rust·前端框架·wasm
H-J-L5 小时前
Web基础与HTTP协议
前端·http·php
Amore05255 小时前
React+TS前台项目实战(二十三)-- 基于属性自定义数值显示组件Decimal封装
前端·react.js·typescript·前端框架
friklogff5 小时前
【JavaScript脚本宇宙】美化网格布局:Isotope和Masonry让你的网页焕然一新
开发语言·前端·javascript