前言先说几句,如果不是接触大型项目,不需要多个子页面,就是完全可以不使用vuex。说实话,当初看vuex文档的时候,很难看懂vuex,甚至觉得不用它也能搞定。但是直到我在项目中遇到了如下问题:路由切换时,原来路由的数据太多,传过去太麻烦。有些数据是多个路由需要的,所以我需要从后台多次获取数据。当然这些问题是可以解决的,就是在实例化Vue对象的时候,把数据绑定到window对象上。但我们也不得不想象:如果数据过多,可读性会不会下降?如果只修改个别数据,是否可以更新所有页面?对于第一个问题,答案是肯定的,虽然,我们现在也可以用模块化的思维来让可读性更好,但是没有一个规范,对于新项目来说总是难以理解。对于第二个问题,当你的页面很少的时候,不会出现这个问题,但是如果页面很多,你会发现当你更新window.$data中的数据时,所有页面的Computedproperties都会失效,即不管你怎么修改数据,页面都不会更新数据。这时候就需要用到我们的vuex了。vuex简介那么vuex到底是什么?官网介绍,Vuex是专门为Vue.js应用开发的状态管理模型。它使用集中存储来管理应用程序所有组件的状态,并使用相应的规则来确保状态以可预测的方式变化。是不是还是有点难以理解,其实简单来说,vuex把这个项目的所有数据都存储在一个地方,方便修改和获取数据。比如下面这张图,给大家简单分析一下。在这张图中,我们可以清楚地看到三个部分。VueComponents表示Vue中的组件。后端API。后端API。vuex组件中的数据管理可以形象的形象化。明白了,如果Vuex是仓库,那么VueComponents就是卖家,负责展示仓库的内容,而BackendAPI相当于买货的人,负责买货(即,后端返回数据给前端,保存在vuex中)。而vuex是一个仓库。这个仓库里面有一个goodstate,还有管理货物进出的Muations。参考vuex在讲state之前,我们可以先参考vuexnpminstallvuex在我们的vue项目中,然后在我们的src目录下新建一个store文件夹。在store文件夹中新建一个index.js文件//~/src/store/index.jsimportVuefrom'Vue'importVuexfrom'Vuex'//在这里声明一个Vue实例来引用Vuex状态管理插件//这样可以减少main.js中的代码量。Vue.use(Vuex)//返回store实例对象exportdefaultnewVuex.Store({})这里说一下,这里的Store其实就是一个vuex实例化仓库。数据替代状态为什么说状态是数据的替代品?很好理解,就是把组件中的局部参数改成全局可以使用的参数状态,比如我们在me.vue组件中引用的数据todo。然后我们可以像这样在store中实例化它//~/src/store/index.js//...exportdefaultnewVuex.Store({state:{todo:[]}})然后,我们在component中如何使用这个数据呢?//me.vue组件文件//...//...等同于//...//...计算属性Getter有时候我们需要对状态数据进行一些过滤操作,比如只需要大于10的数字在todo中,如果我们使用computed,我们需要使用filter函数。为了方便起见,vuex还为我们提供了一个计算属性的getter。我们可以修改~/src/store/index文件//...exportdefaultnewVuex.Store({state:{todo:[]},getters:{todo:state=>state.todo.filter(number=>number>10)}})Thenreferenceinme.vue//...//...这样你就可以很容易的得到todo大于10的数据修改了状态Mutation。我们讲了如何获取数据,那么我们应该如何修改数据呢?直接给数据赋值就够了吗?答案当然不是,vuex规定我们只能使用Mutation来修改数据,那我们怎么修改数据呢?修改我们的~/src/store/index.js//...exportdefaultnewVuex.Store({state:{todo:[]},getters:{todo:state=>state.todo.filter(number=>number>10)},mutations:{revsiseTode:(state,oneTodo)=>(state.todo=oneTodo)//修改state的值}})然后在我们的me.vue组件中修改//...//单独构建版本中的辅助函数是Vuex.mapGettersimport{mapGetters}from'vuex'//单独构建版本中的辅助函数是Vuex.mapMutationsimport{mapMutations}from'vuex'exportdefault{computed:{...mapGetters([//将this.todo映射到store.state.todo'todo'])},method:{...mapMutations([//will`this.revsiseTode()`映射到`this.$store.commit('revsiseTode')`//如果要传递参数,可以使用this.$store.commit('revsiseTode',oneTode)//或者Action'revsiseTode'])}}Action的使用写了这么久,终于是Action的出现了。其实不管怎么说,Action主要是用来和后台交互的一个属性。这里,我假设todo的数据在路由/me/gettodo可以获取到,所以修改~/store/index.js//...exportdefaultnewVuex.Store({state:{todo:[]},getters:{todo:state=>state.todo.filter(number=>number>10)},mutations:{revsiseTode:(state,oneTodo)=>(state.todo=oneTodo)//修改状态值},actions:{getTodo:context=>Vue.http.get('/me/gettodo',(res)=>{context.commit('revsiseTode',res.body.todo)})}})然后我们可以通过触发我们的action来提交mutation来修改状态数据,在me.vue中修改//...//在单独构建的版本中,辅助函数是Vuex.mapGettersimport{mapGetters}from'vuex'//辅助函数是Vuex.mapMutationstodo'])},method:{...mapActions(['reviseTodo',//将`this.reviseTodo()`映射到`this.$store.dispatch('reviseTodo')])}}//...vuex目录结构以上主要只是简单的讲了vuex的使用,而且只是其中的一部分,但是相信看完这里,大家去官网的时候会有更深刻的理解。当然,这些都是简单的用途。如果你想把vuex应用到项目中,你必须把它们模块化才能更好看。vuex官网也为我们提供了一个标准化的项目目录结构,这里就不多说了。综上所述,vuex其实并不难。一开始我觉得很难一直学下去。只要用多了,就会觉得其实只是别人封装的方法而已。我们就用这个简单的仓库吧。
