1.vuex使用回顾//store/index.jsimportVuexfrom"vuex"importVuefrom"vue"Vue.use(Vuex)conststore=newVuex.Store({state:{count:0}getters:{getCount:(state)=>{returnstate.count}},mutations:{changeCount(state,payload){state.count=payload}, },actions:{addCount({commit},payload){ commit("changeCount",payload)}}})exportdefaultstore//main.jsimportstorefrom"./store"newVue({el:"#app",store})二。逐句分析vuex的使用1.vue.use()importVuefrom'vue'importVuexfrom'vuex'Vue.use(Vuex)分析:上面的Vue.use(Vuex)会自动调用vuex的installobject方法,并在install中传入vue实例,保证内外vue实例一致。Vue.use方法可以理解为:Vue.use=(object)=>{object.install(this)}思路:因此,我们重构后的vuex需要对外暴露一个install方法2.newVuex.Store()conststore=newVuex.Store({ state:{...}, getters:{...}, mutations:{...}, actions:{...}})分析:从newVuex.Store()中,我们可以看到导入的Vuex包含一个名为Store的构造函数。思考:根据以上两点,我们可以推断出vuex文件的导出内容大致为:exportdefault{install:(vue)=>{//todo},Store:({state,getters,actions,mutations})=>{ //vuex核心代码 }}3.actionconststore=newVuex.Store({actions:{addCount({commit},payload){ commit("changeCount",payload)}}state:{...},mutations:{...},getters:{...}}分析:这是官方推荐的结构,也可以这样写addCount(context,payload){ context.commit("changeCount",payload)}分析:第二种写法的参数context指的是context环境,也就是store实例上面的第一种写法,因为commit方法可以从这个context中解构出来,不难发现这个store实例包含commit方法3.描述vuexvue的大致结构{ //todo}exportdefault{ Store, install}四、思考如何完成安装:使用t后官方vuex,我们可以在每个组件store中访问this.$,但是我们只将store挂载到main.js中的根实例。按理说只有根实例才能访问store//main.jsimportstorefrom"./store"newVue({el:"#app",store})结论:将store赋值给根实例中的$store,利用Vue组件先父子加载的原则,从根实例的子组件开始,每个组件从父组件获取$store,并将父组件的$store赋值给自己的$storeattributes,这样每个组件都有一个$store属性,都指向同一个store实例letVueletinstall=(_Vue)=>{Vue=_Vue //通过混入beforeCreate生命周期的钩子函数,每个Vue组件都挂载在store上Vue.mixin({beforeCreate(){ //this指向每一个被执行的vue组件 //先判断当前this是否为根实例,因为先执行只有根实例上的$options有存储实例if(this.$options.store){ //根实例 this.$store=this.$options.store}else{ //sofrom根实例从一级组件开始,二级组件可以通过this.$parent获取一级组件的store //然后将它挂载到它自己的$store //等等每个组件Mount$storethis.$store=this.$parent&&this.$parent.$store}}})}exportdefaultinstall5.完成Store中state的思考:store中state的响应是使用Vue中的数据importinstallfrom'./intsall.js'classStore{constructor({state,getters,mutations,actions}){this.state=newVue({data:state}) }}exportdefault{install,Store}6.完成Store中的getterTips:为了方便读者,在下面的内容中,我们将首先列出用法,然后展示函数实现代码getters:{getCount:(state)=>{returnstate.count}},提示:函数实现代码如下:classStore{/*****状态代码*****/constructor({state,getters,mutations,actions}){this.state=newVue({data:state}) } /*****getters代码****/ this.getters={} for(letgetterNameingetters){ //使用Object.deineProperty劫持对this.getter的访问 Object.defineProperty(this.getters,getterName,{get:()=>{ //getter.getCount=(state)=>{returnstate.count} returngetter[getterName](this.vm.state) } }) }}7.在Store中完成mutationsTips:原生使用语法如下:mutations:{changeCount(state,payload){state.count=payload},},Tips:函数实现代码如下:classStore{/*****statecode*****/constructor({state,getters,mutations,actions}){this.state=newVue({data:state}) } /******突变代码****/ this.mutations={} Object.keys(mutations).forEach(mutationName=>{ this.mutations[mutationName]=(newValue)=>{ mutation[mutationName](this.vm.state,newValue) } })}8.完成Store中的commit提示:原生使用语法如下:addCount({commit},payload){commit("changeCount",payload)}提示:函数实现代码如下:classStore{/*****statecode*****/constructor({state,getters,mutations,actions}){this...[mutationName](newValue) }}9.完成Store中的actions提示:原生使用语法如下:actions:{addCount(context,payload){ context.commit("changeCount",payload)}}提示:函数实现代码如下:classStore{/*****statecode*****/constructor({state,getters,mutations,actions}){this.state=newVue({data:state}) } /****动作代码****/ this.actions={} Object.keys(actions).forEach(actionName=>{ this.actions[actionName]=(newValue)=>{ actions[actionName](this,newValue) }})}
