Vue核心知识点 - VueX

本文详细介绍了Vuex在Vue.js中的作用,包括其作为状态管理库的核心概念,如state、getters、mutations和actions,以及如何通过模块化管理和异步操作来优化大型应用程序的状态管理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 一、定义与作用

1、vuex 是什么 ?

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

        个人理解: Vuex 是为 Vue.js 应用程序开发的 状态管理库。

2、状态管理库是什么 ?

        状态管理库是一种用于 管理应用程序中的状态(或数据)的工具或库。在前端开发中,随着应用程序变得越来越复杂,组件之间的数据共享和状态管理 变得更加困难。状态管理库的出现旨在解决这个问题。

3、vuex 作用是什么 ?

作用

帮助我们更好地 管理应用程序中的状态,使得应用程序的数据流变得更加简单和清晰。

应用场景

        在 vue 中,当多个组件需要共享某些状态时,这些状态通常被提升到父组件中,然后通过 props 进行传递,这样就可以实现兄弟组件之间的通信。但是当应用程序变得更加复杂时,这种数据传递方式变得越来越繁琐和难以维护。而 Vuex 的出现,则可以帮助我们更好地管理应用程序中的状态。

4、总结

        vuex 是为 Vue.js 应用程序开发的 状态管理库,当 多个组件需要共享某些状态(或数据) 时,使用 vuex 能够帮助我们更好地管理应用程序中的状态

        中文官网: 

        Vuex 使用手册: 开始 | Vuex

        Vuex API 文档): https://vuex.vuejs.org/zh/api/

二、核心概念

1、state

定义

        表示一个 应用程序的状态 。state 是一个响应式的对象,包含了应用程序中需要共享的数据,例如用户信息、购物车列表等等

作用

        为应用程序提供一个集中式的数据存储,从而可以方便地管理和修改应用程序中的状态。所有的组件都可以访问 state 中的数据,并且当 state 中的数据发生变化时,组件会自动地重新渲染。通过使用 state,我们可以避免在组件之间传递数据的复杂性,使得代码更加简单、清晰和易于维护。

应用场景

        例如,在一个电商应用程序中,购物车的商品列表就可以存储在 state 中,这样不同的组件(例如商品列表、购物车页面、订单页面等等)都可以访问和修改该数据。另外,当应用程序需要实现多语言切换、主题切换等功能时,也可以将当前语言或主题存储在 state 中。

2、getters

定义

        getters 是 Vuex 中的一个概念,它用于对 store 中的 state 进行计算或筛选。getters 可以看作是 store 的计算属性它基于 state 的值进行计算,并返回一个新的值。

作用

        getters 的作用是提供一种方便的方式来获取和处理 store 中的数据,而不需要直接访问和修改 state。getter 可以帮助我们在组件中进行数据的转换、过滤、排序等操作,同时还可以提高代码的可读性和维护性。

应用场景

        对 store 中的数据进行计算或转换:例如,根据购物车列表计算购物车总价、根据用户信息计算用户的年龄等。

        对 store 中的数组进行筛选或排序:例如,从商品列表中筛选出库存大于0的商品、对订单列表按照时间进行排序等

        对 store 中的数据进行过滤或搜索:例如,根据关键字从商品列表中筛选出匹配的商品、根据用户的权限从权限列表中筛选出可见的权限等。

3、mutations

定义

       mutations 是 Vuex 中用于 修改状态(state)的方法(唯一能修改的地方)。它类似于事件,包含一个字符串类型的事件类型(type)和一个回调函数(handler)。通过提交(commit)一个 mutations 来触发对应的回调函数,从而修改状态。

作用

        mutations 的主要作用是 保证状态的可追踪性和可维护性 。由于 Vuex 的状态是响应式的,直接修改状态可能会导致状态变化的来源不明确,难以调试和排查问题。而使用 mutations 来修改状态,可以追踪到每个状态变化的具体来源,并且在 Devtools 中能够记录下每次 mutations 的变化,方便调试和回溯。

应用场景

        修改 store 中的状态:当需要更新 store 中的数据时,可以使用 mutations 来进行状态的修改。例如,添加商品到购物车、更新用户的登录状态等。

        进行同步操作:由于 mutations 是同步执行的,适合处理一些不涉及异步操作的逻辑。例如,计算购物车总价、更新用户的积分等。

        组合多个状态的变化:当需要同时修改多个状态时,可以通过定义多个 mutation 来组合状态的变化。例如,同时更新购物车列表和购物车总价。

        与 actions 配合使用:mutations 和 actions 是密切配合的,actions 可以用来触发 mutations。一般情况下,actions 负责处理异步操作,并通过 commit 方法触发 mutations 来修改状态。

4、actions

定义

        actions 是 vuex 中 用于处理异步操作和提交 mutations 的方法。它类似于 mutations,包含一个字符串类型的事件类型(type)和一个回调函数(handler)。通过分发(dispatch)一个 action 来触发对应的回调函数,从而执行异步操作并提交 mutations。

作用

        actions 的主要作用是处理异步操作和复杂的业务逻辑。由于 mutations 只能进行同步操作,不能处理异步任务,而 actions 可以通过包裹异步操作的方式来处理这些任务,并在完成后提交 mutations 来修改状态。另外,actions 还可以用于组合多个 mutations 的提交,实现更复杂的状态变化。

应用场景

        执行异步操作:当需要进行异步操作时,例如发送网络请求、定时器等,可以将异步操作放在 actions 中处理,确保状态的正确更新。

        处理复杂的业务逻辑:当需要进行复杂的业务逻辑处理时,可以将逻辑放在 actions 中,并根据需要触发 mutations 或其他 actions,实现状态的变化。

        组合多个 mutations 的提交:actions 可以用于组合多个 mutations 的提交,实现一次 dispatch 操作对应多个状态的变化。这样可以减少组件中的重复代码,提高代码的复用性和可读性。

        与异步组件配合使用:在使用 Vue 的异步组件时,可以通过 actions 来触发加载动作,并在异步组件加载完成后提交 mutations 更新状态。

5、modules

定义

        modules 是用于将大型的状态树拆分成模块化的方式。每个模块都可以有自己的 state、mutations、actions 和 getters,从而将复杂的应用状态分解为更小的、可维护的模块。

作用

        拆分大型的状态树:当应用的状态树非常庞大时,使用 Modules 可以将其拆分为多个小模块,每个模块负责管理自己的状态,从而提高代码的组织性和可维护性。

        避免命名冲突:Modules 允许在每个模块中定义局部的 state、mutations、actions 和 getters,这样可以避免命名冲突,并且更容易理解和调试特定模块的代码。

        提供命名空间:每个模块可以设置命名空间(namespace),通过命名空间可以在不同模块之间进行数据通信,避免全局污染和冲突。

        实现代码复用:通过将相关的状态和操作放在一个模块中,可以提高代码的复用性。多个组件可以共享同一个模块,避免重复编写相似的代码。

        分工协作:Modules 可以根据团队成员的分工,将应用状态的管理任务分配给不同的模块,使团队成员可以独立开发和维护各自负责的模块。

应用场景

        大型应用:当应用的状态树非常庞大时,使用 Modules 可以将其拆分为多个模块,每个模块负责管理特定的状态和逻辑。这样可以提高代码的组织性和可维护性。

        多人协作:在团队开发中,不同的团队成员可以负责不同的模块,通过 Modules 可以将应用状态的管理任务分配给不同的模块,实现并行开发和分工协作。

        代码复用:当多个组件需要共享同一部分状态和逻辑时,可以将其放在一个模块中,并在需要的组件中引入该模块。这样可以提高代码的复用性,避免重复编写相似的代码。

        命名空间:当应用中存在多个具有相同类型的模块时,可以通过设置命名空间来区分它们,避免命名冲突,并且可以在不同模块之间进行数据通信。

三、具体使用(演示代码)

1、创建 Vuex 模块

src/store/modules/user.js

// 举例的 Vuex 模块

// 导入调用接口的方法
import { getInfo } from '@/api/user'

// 状态:存储状态值
const state = {
  userInfo: {}
}

// 变更: 唯一能修改状态值的方法
// Mutation 方法接收两个参数,第一个参数是当前的 state 对象,第二个参数是 payload(可选),用于传递额外的数据
const mutations = {
  setUserInfo(state, data) {
    state.userInfo = data
  }
}
// Actions 用于处理异步操作和复杂的业务逻辑。
// Actions 方法接收两个参数,第一个参数是当前的 commit 对象,第二个参数是 payload(可选),用于传递额外的数据
const actions = {
  async getInfo(context, username) {
    const { data } = await getInfo(username)
  	// 调用 Mutation 的方法 当前模块
    context.commit('setUserInfo', data)
    // 调用 Mutation 的方法 其他模块
    // context.commit('user/setUserData', data, { root: true });
    // 如果是调用当前模块异步的方法(假设eg是当前模块下的一个action方法)
    // context.dispatch('eg', egdata)
    // 如果是调用其他模块异步的方法(假设fetchUserData是user模块下的一个action方法)
    // context.dispatch('user/fetchUserData', payload, { root: true });
    // 如果是调用视图模块的异步方法 tagsView-对应模块名称 delAllView-对应方法名称
    // dispatch('tagsView/delAllViews', null, { root: true }
  }
}

// 导出数据
export default {
  namespace: true, // 开启命名空间
  state,
  mutations,
  actions
}

2、配置 getter 对象

src/store/getter.js

// getters 计算属性
const getters = {
  sidebar: state => state.app.sidebar, //举例说明 src/modules/app.js 模块下 sidebar 状态值
  size: state => state.app.size,
  device: state => state.app.device,
  visitedViews: state => state.tagsView.visitedViews,
  cachedViews: state => state.tagsView.cachedViews,
  token: state => state.user.token,
  avatar: state => state.user.avatar,
  name: state => state.user.name,
  introduction: state => state.user.introduction,
  roles: state => state.user.roles,
  permission_routes: state => state.permission.routes,
  errorLogs: state => state.errorLog.logs
}
export default getters

3、配置 vuex 的入口文件

src/store/index.js

import Vue from 'vue'
import Vuex from 'vuex'
import getters from './getters'

Vue.use(Vuex)

// Webpack的require.context函数来动态加载./modules目录下所有以.js结尾的模块文件
/**
 * @ params 文件夹路径 是否还搜索子目录 正则表达式匹配的文件后缀名
 * @ return function
 */
const modulesFiles = require.context('./modules', true, /\.js$/)

// 将每个模块文件导入并组织成一个以模块名为属性名的对象。
const modules = modulesFiles.keys().reduce((modules, modulePath) => {
  // set './app.js' => 'app'
  const moduleName = modulePath.replace(/^\.\/(.*)\.\w+$/, '$1')
  // 获取文件模块
  const value = modulesFiles(modulePath)
  // 模块对象 { 文件名: 模块默认导出值 }
  modules[moduleName] = value.default
  return modules
}, {})

// 创建了一个 Vuex 的 store 实例
const store = new Vuex.Store({
  modules, // 是一个包含了所有模块的对象
  getters // 包含了一些计算属性的对象
})

export default store

4、main.js 配置

import Vue from 'vue';
import Vuex from 'vuex';
import store from './store';

Vue.use(Vuex);

new Vue({
  store,
  // 其他配置项
}).$mount('#app');

5、vue 组件引用

方式一、直接引用
// 未开启命名空间
// 获取 state
this.$store.state.myState

// 调用 mutation
this.$store.commit('myMutation', payload)

// 调用 action
this.$store.dispatch('myAction', payload)

// 获取 getter
this.$store.getters.myGetter


// 开启命名空间
// 获取 state
this.$store.state.moduleName.myState

// 调用 mutation
this.$store.commit('moduleName/myMutation', payload)

// 调用 action
this.$store.dispatch('moduleName/myAction', payload)

// 获取 getter
this.$store.getters['moduleName/myGetter']
方式二、借助辅助函数应用
import { mapState, mapMutations, mapActions, mapGetters } from 'vuex'

export default {
  // 未开启命名空间
  computed: {
    ...mapState(['myState']),
    ...mapGetters(['myGetter'])
  },
  methods: {
    ...mapMutations(['myMutation']),
    ...mapActions(['myAction'])
  }
}
import { mapState, mapMutations, mapActions, mapGetters } from 'vuex'

export default {
  // 开启了命名空间
  computed: {
    ...mapState('moduleName', ['myState']),
    ...mapGetters('moduleName', ['myGetter'])
  },
  methods: {
    ...mapMutations('moduleName', ['myMutation']),
    ...mapActions('moduleName', ['myAction'])
  }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值