用浅显易懂的语言讲解vuex

本文深入解析Vuex,Vue.js的状态管理模式,阐述其在组件间通信中的核心作用,以及如何通过store对象管理应用状态,包括state、getter、mutation、action和module的概念与实践。

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

一.什么是vuex

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

个人理解:Vuex提供了一个储存数据的地方,但它的核心作用在于封装操作数据的方法。

二.为什么要用Vuex?

我们知道组件之间是独立的,组件之间想要实现通信,除了vuex还有三种方法,父子组件之间通信使用$emit和props,非父子组件只能用eventbus(事件总线),但事件总线使用起来较为繁琐。试想一下,当做中大型项目时,面对一大堆组件之间的通信,还有一大堆的逻辑代码,会不会很抓狂??那为何不把组件之间共享的数据给“拎”出来,在一定的规则下管理这些数据呢? 这就是Vuex的基本思想了。

三.怎么使用Vuex?

从官方文档可以看到,vuex的核心就是store对象(数据库管理系统),store有五个核心概念,分别是state,getter,mutation,action,module。我们先来概述一下,然后再结合代码来具体讲解。

store对象中有四部分,state(相当于数据存储器),就是存储数据的地方。getter(数据处理方法),很多时候我们需要把数据处理之后再用,每次用的时候都处理很明显不方便,所以我们把数据处理方法集中放到getter中。mutation(同步改变数据方法),当我们要改变state中的数据时,不能直接改变state中的数据,只能通过mutation中的方法来改变,mutation中的方法必须是同步的。action(异步改变数据方法)。当我们要异步改变state中的数据时,就要通过action,但action改变数据也是依靠mutation。

借助官方的图可以更好地理解:

在组件中改变vuex中的数据时,首先使用dispatch(就是store自带的调用actions的方法)调用actions中的异步改变数据方法,然后由actions中的方法使用commit(store调用mutation的方法)调用mutations中的方法改变数据。当然,图中这是异步改变数据,当我们只是同步改变数据时,直接使用commit调用mutations中的方法就可以。通过mutations改变的state中的数据会响应式的显示在页面上。

module是一个store模块化的方案,当我们在store中的数据很多时,各种方法写在一起看起来会很臃肿,为了解决这个问题,Vuex 允许我们将 store 分割成模块。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割。

结合代码来实战演练一下:

1.创建store实例

Vue.use(Vuex)
const store = new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    increment (state) {
      state.count++
    }
  }
})

在上面的代码中,首先new了一个vuex实例,实例中有state和mutations。state对象就是我们的数据库, 其中保存了一个属性count值为0。mutations对象中保存的是我们操作state的方法。

然后我们将store挂载在vue实例上, store 实例会注入到根组件下的所有子组件中,且子组件能通过 this.$store 访问到。

new Vue({
  el: '#app',
  router,
  store,
  components: { App },
  template: '<App/>'
})

 这时我们就可以在vue实例中使用vuex了,我们要把需要用到的store中的值写在计算属性中。

<template>
  <div id="app">
     {{count}}
  </div>
</template>

<script>
export default {
  name: 'App'
},
  computed: {
    count () {
      return this.$store.state.count
    }
  }
</script>

 但当数据很多的时候,都这样声明在计算属性中就显得很麻烦,vuex提供了mapState 辅助函数,我们可以像下面这样改写一下

import {mapState} from 'vuex'
export default {
  name: 'HomeHeader',
  computed: {
    mapState(['count'])
  }
}

如果是多个数据的话我们还可以用对象展开运算符

  computed: {
    ...mapState(['count','number'])
  }

这种写法对于某些童鞋来说可能会比较懵,我们来分析一下,

mapState是一个函数,返回一个对象,他的本质大概是这个样子滴:

function mapState(){return {count:1,number:2}}
var data={ mapState() }  //这样肯定会报错的  
var data = { ...mapState() } //这样就能正确展开
data = {
count:1;
number:2;
}

2.mutation

想要改变count时,必须使用commit调用mutations中的方法

this.$store.commit('increment')  //调用mountations中的方法
console.log(store.state.count) // -> 1

同样的mutations中也提供了辅助函数mapMutations:

...mapMutations(['increment'])
this.increment()

方法中是可以传入参数的,mutatinos方法中默认传入的第一个参数为state,actions和getter的方法也是一样的:

mutations: {
  increment (state, n) {
    state.count += n
  }
}
this.$store.commit('increment', 10)
//或者这样
...mapMutations(['increment'])
this.increment(10)

3.action

Action 提交的是 mutation,而不是直接变更状态。action不同于mutation,action 函数接受一个与 store 实例具有相同方法和属性的 context 对象而不是store本身。我们使用参数结构省略了context,写成了{commit}

const store = new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    increment (state) {
      state.count++
    }
  },
  actions: {
    incrementAsync ({ commit }) {
      setTimeout(() => {
        commit('increment')
    }, 1000)
  }
})

调用actions中的方法使用dispatch

this.$store.dispatch('incrementAsync')

同样的actions也有辅助函数mapActions,在这里不再多说。

store.dispatch()方法返回的是一个promise对象,所以我们可以像使用promise时那样写

store.dispatch('actionA').then(() => {
  // ...
})

 4.getter

很多时候我们直接从store中拿到的数据是不能使用的,需要经过处理,但每次使用的时候都写代码处理一次就比较麻烦,所以vuex为我们提供了getter,在getter中保存对数据处理的方法


Vue.use(Vuex)
const store = new Vuex.Store({
  state: {
    todos: [1,2,3]
  },
  mutations: {
    increment (state) {
      state.count++
    }
  }
})
computed: {
  doneTodosCount () {
    return this.$store.state.todos.filter((n) => n<2).length
  }
}

 对于上面的这种情况,我们可以将下面这段代码加到store实例中

 getters: {
    doneTodos: state => {
      return state.todos.filter((n) => n<2)
    }
  }

 然后通过下面这样来调用

this.$store.getters.doneTodos

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值