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 观察状态变化。
相关推荐
腾讯TNTWeb前端团队1 小时前
helux v5 发布了,像pinia一样优雅地管理你的react状态吧
前端·javascript·react.js
范文杰4 小时前
AI 时代如何更高效开发前端组件?21st.dev 给了一种答案
前端·ai编程
拉不动的猪4 小时前
刷刷题50(常见的js数据通信与渲染问题)
前端·javascript·面试
拉不动的猪4 小时前
JS多线程Webworks中的几种实战场景演示
前端·javascript·面试
FreeCultureBoy5 小时前
macOS 命令行 原生挂载 webdav 方法
前端
uhakadotcom6 小时前
Astro 框架:快速构建内容驱动型网站的利器
前端·javascript·面试
uhakadotcom6 小时前
了解Nest.js和Next.js:如何选择合适的框架
前端·javascript·面试
uhakadotcom6 小时前
React与Next.js:基础知识及应用场景
前端·面试·github
uhakadotcom6 小时前
Remix 框架:性能与易用性的完美结合
前端·javascript·面试
uhakadotcom6 小时前
Node.js 包管理器:npm vs pnpm
前端·javascript·面试