本文系统介绍vuex的全部内容
-
为什么用vuex
组件通信知道吧,相信很多同学,刚学的时候很难懂,实时上在实际应用中,大型项目如果使用最原始的组件通信会非常的麻烦,主要体现在多层嵌套的组件之间的通信,使用vuex可以很方便的处理和维护state
-
开始
1.vuex的特点 **当store容器中的数据发生变化了,那么组件中的数据也会跟着发生变化 **更改store中的state值,必须使用commit 2.安装 npm install vuex --save Vue.use(Vuex) 3.基本使用 const store = new Vuex.Store({ state: { count: 0 }, mutations: { increment(state){ state.count++ } } })
-
state
在单文件系统中,组件都是单独的文件如果想访问到vuex的store中的数据需要重复的导入store文件,非常麻烦,可以使用如下方式,只需导入一次即可 const app = new Vue({ el: '#app', store, ... }) 就是将store实例,直接赋值给vue根组件的store属性,然后在此根组件下面所有的子组件都可以通过this.$store.state访问到store中的state 一般获取到store中的某个属性值,会在组件中使用计算属性重新声明一个属性,如下 const Counter = { template: '<div>{{count}}</div>', computed: { count(){ return this.$store.state.count } } } 如果你需要的属性值,很多,那么你叫重复的写很多类似的代码,很麻烦,这时可以使用mapState辅助函数,使用方法如下 import {mapState} from 'vuex' //导入辅助函数 export default { computed: mapState({ count: state => state.count // 不做任何处理直接导入 count: 'count' // 和上面的作用一样 count // 同名的可以直接简写 count(state){ return state.count + this.otherValue } // 做特殊处理 }) } 上面可以看到一个mapState将一个computed全占了,这时我要是有自己的计算属性可以使用对象展开运算符 computed: { localComputed(){}, ...mapState({ //... }) }
-
getters
有些store中的state,并不是组件中需要的数据,而组件要的是基于这个state通过计算后的值,这时可以在store中使用getters选项,这和组件的computed的功能是一模一样的 const store = new Vuex.Store({ state: { a: 1 }, getters: { incre: state => { return state.a + 1 } } }) 那么incre就是2了 可以通过store.getters.a或者this.$store.a访问 还可以传递其他的getters,后面具体讲解 incre: (state,getters) => { return getters.a + 1 } mapGetters函数的使用 和mapState一样 import { mapGetters } from 'vuex'; export default { computed: { ..., ...mapGetters([ 'incre' ]) } }
-
mutations
mutation就是用来同步的修改state中的数据的 const store = new Vuex.Store({ state: { count: 1 }, mutations: { increment(state,value){ state.count++ } } }) 调用mutation中的方法需要 store.commit('increment') 传递数据 store.commit('increment', 10) 为了保证好的代码风格,可以统一的传递对象 mutations: { increment (state,payload) { state.count += payload.amount } } store.commit('increment',{ amount: 10 })或者 store.commit({ type: 'increment', amount: 10 }) 注意:mutation只能写同步的函数,至于原因是vue的devtool无法捕捉状态,这个devtool几乎用不上 使用mapMutations函数 在组件中使用mutations中的函数,最好都放在methods里面,方便管理 import { mapMutations } from 'vuex' methods: { ..., ...mapMutations([ 'increment' ]) }
-
actions
其实actions的功能和methods类似,可以用来处理异步的函数,然后将结果通过mutation传递 actions: { incre(context){ context.commit('increment') } } // context 具有和store相同的属性和方法 也可以使用es6的语法 actions: { incre({commit}) { commit('increment') } } 触发action中的方法 store.dispatch('incre') 或者 store.dispatch('incre',{ amount: 10 }) 或者 store.dispatch({ type: 'incre', amount: 10 }) 使用mapActions函数 import { mapActions } from 'vuex'; export default { ..., ...mapActions([ 'increment' ]) }
-
modules
这部分内容其实就是将如何将一个store拆分成多个小的store const moduleA = { state: {...}, ... } const store = new Vuex.Store({ modules: { a: moduleA } }) 这就把A模块合并到store中了,通过store.state.a访问moduleA的state 你要清楚,本质上着就是合并对象,所以你可以使用平常的methods和mutations等使用方法,因为他们实际上就是合并成了一个methods或者mutations等,所以这样就会有一个问题,子模块和子模块、主模块之前的命名冲突问题,但是注意,细心的同学可能发现了,上面介绍的store.state.a这样不可能出现命名冲突,这是对的,因为vue默认只对state做了分开的处理,所以你在子模块中的actions这类的属性中访问到主模块store中的数据必须传递第三个参数rootState,如下 const moduleA = { actions: { incre({state,commit,rootState}) { ... } } } 要解决上面提到的命名冲突的问题就要使用到命名空间,如下 const moduleA = { // 添加下面这句话,这个模块就是独立的了,不会和外界发生冲突 namespaced: true, // state不会受到命名空间的影响 // 在外界要访问到此模块的getters,actions等,需要添加路径 getters: { isAdmin(){....} // getters['moduleA/isAdmin'] } } 在命名空间中访问主模块的数据要添加 rootState,rootGetters 细节自查官网,用的真心很少,不同的模块的actions这类的名字能取成一样的也是奇葩
结语
还有一部分内容对于开发来说,没有任何作用,学习就要把自己宝贵的时间放在对你最有用的东西上面
这部分内容是我关于vue的最后的一篇知识归纳,以后将全身心的投入到react的学习当中