Vuex实现数据共享的方法
在用vue作为前端框架进行开发的时候,对于组件间的传值你一定不会陌生,如果只是简单的父子组件传值,我想你肯定不会选择用Vuex来进行状态管理,但是如果你需要构建一个中大型单页应用,组件间数据交互比较复杂频繁,你很可能会考虑如何更好地在组件外部管理状态,那么Vuex将会成为自然而然的选择。
Vuex是什么?
Vuex是一个专为Vue.js应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。这是官方的一种说法。
用个人的话总结下: Vuex就是为了实现多组件数据共享,从而建立一个叫store的数据管理库,将需要共享的数据存放在里面,在需要的地方可以取出来作为初始数据,也可以在组件内通过dispatch或者提交commit方法来改变该原始数据状态,从而实现的data的共享。
Vuex的核心
1、State
Vuex中的数据源,我们需要保存的数据就保存在这里,可以在页面通过this.$store.state来获取我们定义的数据。
importVuefrom"vue"; importVuexfrom"vuex"; Vue.use(Vuex); conststate={ number:0 } exportdefaultnewVuex.Store({ state, });
在页面中通过this.$store.state.number即可获取到当前的值。
2、Getter
Vuex允许我们在store中定义“getter”(可以认为是store的计算属性)。就像计算属性一样,getter的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。
Getter接受state作为其第一个参数:
importVuefrom"vue"; importVuexfrom"vuex"; Vue.use(Vuex); conststate={ number:0 } constgetters={ getNumber(state){ returnstate.number+1 } } exportdefaultnewVuex.Store({ state, getters, });
在页面你可以用两种方式取到getters里面的值
1、通过属性访问
Getter会暴露为store.getters对象,你可以以属性的形式访问这些值如:this.$store.getters.getNumber
Getter也可以接受其他getter作为第二个参数:
conststate={ number:1 } constgetters={ getNumber(state){ returnstate.number+1//2 }, getDoubNUmber(state,getters){ returnstate.number+getters.getNumber//3 } }
注意:getter在通过属性访问时是作为Vue的响应式系统的一部分缓存其中的。
2、通过方法访问
你也可以通过让getter返回一个函数,来实现给getter传参。在你对store里的数组进行查询时非常有用。
conststate={ number:1, list:[1,2,3,4,5] } constgetters={ getNumber(state){ returnstate.number+1//2 }, getDoubNumber(state,getters){ returnstate.number+getters.getNumber//3 }, filterNumber:(state)=>(num)=>{ returnstate.list.find(item=>item%num===0) } } exportdefaultnewVuex.Store({ state, getters, });
注意, getter在通过方法访问时,每次都会去进行调用,而不会缓存结果this.$store.getters.filterNumber(3)
3、Mutation
更改Vuex的store中的状态的唯一方法是提交mutation。Vuex中的mutation非常类似于事件:每个mutation都有一个字符串的事件类型(type)和一个回调函数(handler)。这个回调函数就是我们实际进行状态更改的地方, 并且它会接受state作为第一个参数, 提交载荷(payload)作为额外的参数,并且在大多数情况下,载荷应该是一个对象,这样可以包含多个字段并且使记录的mutation会更易读:
你可以这样写:
constmutations={ increment(state,n){ state.number+=n } }
但你不能直接调用一个mutationhandler。这个选项更像是事件注册:“当触发一个类型为increment的mutation时,调用此函数。”要唤醒一个mutationhandler,你需要以相应的type调用 store.commit方法:
this.$store.commit('increment',1)
也可以这样写:
constmutations={ increment(state,payload){ state.number+=payload.count } }
然后:
使用this.$store.commit('increment',{count:1}) 提交,
//或者另一种方式是直接使用包含type属性的对象进行提交: this.$store.commit({ type:'increment', count:1 })
特别说明:在Vuex中,mutation都是同步任务:为了处理异步操作,让我们来看一看Action。
4、Action
Action类似于mutation,不同在于:
1、Action提交的是mutation,而不是直接变更状态。
2、Action可以包含任意异步操作。
虽然在页面中通过提交commit是可以达到修改store中状态值的目的,但是官方并不建议我们这样做,而是让我们去提交一个action,在action中提交mutation再去修改状态值。
constmutations={ increment(state){ state.number+=1 } } constactions={ addNumber(context){ context.commit('increment') } }
Action函数接受一个与store实例具有相同方法和属性的context对象,因此你可以调用context.commit提交一个mutation,或者通过context.state和context.getters来获取state和getters
addNumber({commit}){ commit('increment') }
以上这种写法等同于:
addNumber(context){ context.commit('increment') }
Action通过store.dispatch方法触发:
this.$store.dispatch('addNumber')
同mutation一样你也可以在action的时候传递参数
constmutations={ increment(state,number){ state.number+=number } } constactions={ addNumber(context,number){ context.commit('increment',number) } 或者: addNumber({commit},number){ commit('increment',number) } }
触发方法:this.$store.dispatch('addNumber',10)
关于在action处理异步操作可以看下面这个例子:
constactions={ getData({commit}){ returnnewPromise((resolve,reject)=>{ setTimeout(()=>{ commit('getList') resolve() },1000) }) } }
然后再
this.$store.dispatch('getData').then(()=>{ //... })
完整实例:
importVuefrom"vue"; importVuexfrom"vuex"; import{resolve,reject}from"any-promise"; Vue.use(Vuex); conststate={ number:1, list:[1,2,3,4,5] } constgetters={ getNumber(state){ returnstate.number+1//2 }, getDoubNumber(state,getters){ returnstate.number+getters.getNumber//3 }, filterNumber:(state)=>(num)=>{ returnstate.list.find(item=>item%num===0) } } constmutations={ increment(state,n){ state.number+=n }, getList(state){ state.list=state.list.forEach((item)=>item*2) } } constactions={ addNumber({commit},n){ commit('increment',n) }, getData({commit}){ returnnewPromise((resolve,reject)=>{ setTimeout(()=>{ commit('getList') resolve() },1000) }) } } exportdefaultnewVuex.Store({ state, getters, mutations, actions });
关于Vuex中mapState、mapGetters、mapMutations、mapActions的用法
要用首先得引入:
import{mapState,mapGetters,mapMutations,mapActions}from'vuex';
这玩意儿其实就是Vuex内置的辅助函数,方便我们获取store里面的数据和方法
computed:{ ...mapState([ 'number' ]) } //使用对象展开运算符将getter混入computed对象中 computed:{ ...mapGetters([ 'getNumber', 'getDoubNumber', //... ]) } methods:{ ...mapMutations([ 'increment',//将`this.increment()`映射为`this.$store.commit('increment')` ...mapMutations({ add:'increment'//将`this.add()`映射为`this.$store.commit('increment')` }) } methods:{ ...mapActions([ 'addNumber',//将`this.addNumber()`映射为`this.$store.dispatch('addNumber')` //`mapActions`也支持载荷: 'addNumber'//将`this.addNumber(amount)`映射为`this.$store.dispatch('addNumber',amount)` ]), ...mapActions({ requestData:'getData'//将`this.requestData()`映射为`this.$store.dispatch('getData')` }) }
以上是对Vuex实现状态管理的一个整个过程的理解,参考官方文档,然后自己写一遍,比较容易明白其中的道理,后面有时间想写React里面关于Redux实现状态管理的一个过程,对比其中,其实他们思想差不多,只不过redux实现过程更多点,敬请期待!
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。