vuex深入浅出

本文主要记录使用vuex的使用场景、重要组成部分和学习心得。原文参考我的个人博客(文章格式看起来更好看(●'◡'●))vuex深入浅出

1、说在前面

学习vue有两周的时间了,目前已经对vue的基础使用比较熟悉了。但是一直对vuex的使用耿耿于怀,这么说是因为总是不太理解,还好经过实践和深入阅读官网后现在总算有了一定的掌握,这里做一下学习笔记和使用心得。

2、什么是vuex

vuex是vue的状态管理模式,它集中管理所有组件的共享状态,并且有自己的规则,比如怎么修改状态的值,怎么获取状态的值,是以一种可预测的方式来监听状态的改变。

3、为什么要使用vuex

我们知道,组件的通信(单向数据流)有两种:

  • 1、父->子通信,通过props
  • 2、子->父通信,通过触发$emit的方法
    那么,兄弟组件的通信呢?(当然简单的也可以通过子->父->子的方法传递,但是还是比较麻烦的),那么不相关的组件之间的通信呢?这就是vuex存在的主要意义。用官网上的话就是解决:
  • 1、多个视图依赖同一个状态
  • 2、来自不同视图的行为变更同一个状态

4、vuex的组成

State

state中定义共享的状态值

//state.js
export default state = {
    count: 0
}

获取state的值,需要放在计算属性中,保证每次state能够响应式的获取

computed:{
    count(){
        return this.$stores.state.count //获取值
    }
}

这种获取方式是比较繁琐的,因此vuex给我们提供的对应的语法糖 mapState,便于我们简洁性的获取值

import { mapState } from 'vuex'

export default{
    computed:{
        ...mapState(['count']) //这样我们在组件就可以通过this.count获取对应的值了
    }
}

Getter

state的派生状态值,可以理解成是store的计算属性,它一般是一个方法,方法接受一个参数state

//getter.js
export default {
    getCount: state => state.count + 1
}

它的辅助函数是mapGetter,一般也放在computed里

import { mapGetters } from 'vuex'
export default {
  computed: {
  // 使用对象展开运算符将 getter 混入 computed 对象中
    ...mapGetters(['getCount'])
  }
}

Mutation

vuex规定更改state的值唯一方法是提交 mutation,原因是为了能够明确的追踪状态的变化,它接受2个参数(state,newVal),第二个参数可以是字符串也可以是对象

//mutations.js
export default {
    setCount(state,newVal){
        state.count = newVal
    }
}

必须通过commit的方法触发调用它

this.$store.commit('setCount',20) //此时你把state中的count的值变成了20

它的辅助函数是mapMutations,它一般放在methods中

import { mapMutations } from 'vuex'
export default {
  methods: {
    ...mapMutations(['setCount'])
  }
}

在 Vuex 中,mutation 都是同步事务,不可写入异步操作

Action

Action 类似于 mutation,它主要用于:

  • 批量的同步操作
  • 异步操作
    它接受一个store 实例具有相同方法和属性的 context 对象,注意它提交的是 mutation,而不是直接变更状态

    //actions.js
    export default {
    increment(context){
        context.commit('setCount')
    }
    }

    在实践中可以通过参数解构的方法简化代码

    increment({commit}){
        commit('setCount')
    }

    在组件中通过分发dispatch的方法来触发action

    this.$store.dispatch('increment')

    这样做的目的是为了可以在action的内部执行异步操作(比如通过接口请求后才更改state的值)

    increment({commit}){
        setTimeout(()=>{
            commit('setCount')
        },1000)
    }

    也可以同步批量更改state中的值

    increment({commit}){
        commit('mutation1')
        commit('mutation2')
        commit('mutation3')
    }

它的辅助函数是mapActions,一般放在methods中

import { mapActions } from 'vuex'

export default {
  methods: {
    ...mapActions(['increment']) //将 this.increment() 映射为 this.$store.dispatch('increment')
  }
}

action的返回接收,可以返回一个Promise

export default{
    actionA ({ commit }) {
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                commit('someMutation')
                resolve()
            }, 1000)
        })
    }
}

数据接受后处理

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

5、vuex的定义

我们一般会在src目录下建立一个名为store的文件夹专门放vuex的文件,目录里存放

  • state.js:所有需要管理的状态
  • getters.js:所有需要更派生的状态
  • mutations.js :所有需要更改状态的方法
  • actions.js: 所有需要异步或批量同步更改状态的方法
  • index.js: 主入口文件
    代码
import Vue from 'vue'
import VueX from 'vuex'
import States from './state'
import Getters from './getters'
import Mutations from './mutations'
import Actions from './actions'

Vue.use(Vuex)
export default nex Vuex.Store({
    State,
    Getters,
    Mutations,
    Actions
})

然后在根目录下的main.js中全局引入

import store from './store'

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

6、总结

总的来说,当把所有的应用梳理一遍后vuex也没有那么的高深莫测,一切源于实践吧!实践比直接阅读或看文档更加的印象深刻。当然,还有一些应用官网上说的很明确,这里不在重述。比如:

猜你喜欢

转载自www.cnblogs.com/webhmy/p/9160474.html