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(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。