- 组件之间共享数据的方式:
- 父向子传值:v-bind属性绑定;
- 子向父传值:v-on事件绑定;
- 兄弟组件之间共享数据:EventBus($on: 接收数据的那个组件, $emit: 发送数据的那个组件)
- 使用vuex进行统一状态管理的好处:
- 能够在vuex中统一管理共享的数据,易于开发和后期维护;
- 能够高效地实现组件之间的数据共享,提高开发效率;
- 存储在vux中都数据都是响应式的,能够实时保持数据与页面的同步。
- 什么样的数据适合存储到vuex中:
一般情况下,只有组件之间共享的数据,才有必要存储到vuex中;对于组件中的私有数据,依旧存储在组件自身的data中即可。
- vuex的核心概念:
State, Mutation, Action, Getter
- State
State提供唯一的公共数据源,所有共享的数据都要放到Store的State中进行存储
定义:
state: { count: 0 }
调用方式一:
<p>{{$store.state.count}}</p>
调用方式二:
import {mapState} from 'vuex'
export default{
computed:{
...mapState(['count'])
}
}
<p>{{count}}</p>
- Mutation
Mutation用于变更store中的数据。
- 只能通过Mutation变更store数据,不可以直接操作store中的数据;
- 通过这种方式虽然操作起来稍微繁琐一些,但是可以集中监控所有数据的变化。
定义:
mutations:{ add(state){ //不带参数 state.count++ }, addN(state, step){ //带参数 state.count+= step } }
调用方式一:
methods:{ add(){ this.$store.commit('add') //不带参数 }, add3(){ this.$store.commit('addN', 3) //带参数 } }
调用方式二:
import {mapMutations} from 'vuex'
methods:{
...mapMutations(['add','addN'])
handleAdd(){
this.add() //不带参数
},
add3(){
this.addN(3) //带参数
}
}
- Action
Action用于处理异步任务。
如果通过异步操作变更数据,必须通过Action,而不能使用Mutation,但是在Action中还是要通过触发Mutation的方式间接变更数据。
定义:
actions:{ addAsync(context){ //不带参数 setTimeout(()=>{ context.commit('add') }, 1000) }, addNAsync(context, step){ //带参数 setTimeout(()=>{ context.commit('addN', step) }, 1000) } }
调用方式一:
methods:{ addAsync(){ this.$store.dispatch('addAsync') //不带参数 }, add3Async(){ this.$store.dispatch('addNAsync', 3) //带参数 } }
调用方式二:
methods:{ ...mapActions(['addAsync', 'addNAsync']), handleAddAsync(){ this.addAsync() //不带参数 }, add3Async(){ this.addNAsync(3) //带参数 } }
- Getter
Getter用于对store中的数据进行加工处理形成新的数据。
- Getter可以对store中已有的数据加工处理之后形成新的数据,类似vue的计算属性;
- store中数据发生变化,Getter的数据也会跟着变化。
定义:
getters: { showCount: state => { return '当前count值为:' + state.count } }
调用方式一:
<p>{{$store.getters.showCount}}</p>
调用方式二:
import {mapGetters} from 'vuex'
computed:{
...mapGetters(['showCount'])
}
<p>{{showCount}}</p>
- 综合实例
main.js
// The Vue build version to load with the `import` command // (runtime-only or standalone) has been set in webpack.base.conf with an alias. import Vue from 'vue' import App from './App' import store from './store/index.js' Vue.config.productionTip = false /* eslint-disable no-new */ new Vue({ el: '#app', store, //挂载到全局 components: { App }, template: '<App/>' })
store.js
import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) export default new Vuex.Store({ state: { count: 0 }, getters: { showCount: state => { return '当前count值为:' + state.count } }, mutations:{ add(state){ state.count++ }, addN(state, step){ state.count+= step }, sub(state){ state.count-- }, subN(state, step){ state.count-= step } }, actions:{ addAsync(context){ setTimeout(()=>{ context.commit('add') }, 1000) }, addNAsync(context, step){ setTimeout(()=>{ context.commit('addN', step) }, 1000) }, subAsync(context){ setTimeout(()=>{ context.commit('sub') }, 1000) }, subNAsync(context, step){ setTimeout(()=>{ context.commit('subN', step) }, 1000) } } })
addition.vue(通过方式一调用store)
<template>
<div>
<p>{{$store.state.count}}</p>
<p>{{$store.getters.showCount}}</p>
<button @click="add()">+1</button>
<button @click="add3()">+3</button>
<button @click="addAsync()">+1 Async</button>
<button @click="add3Async()">+3 Async</button>
</div>
</template>
<script>
export default{
name: 'Addition',
methods:{
add(){
this.$store.commit('add')
},
add3(){
this.$store.commit('addN', 3)
},
addAsync(){
this.$store.dispatch('addAsync')
},
add3Async(){
this.$store.dispatch('addNAsync', 3)
}
}
}
</script>
<style>
</style>
subtraction.vue(通过映射的方式调用store)
<template>
<div>
<p>{{count}}</p>
<p>{{showCount}}</p>
<button @click="handlesub()">-1</button>
<button @click="sub3()">-3</button>
<button @click="handlesubAsync()">-1 Async</button>
<button @click="sub3Async()">-3 Async</button>
</div>
</template>
<script>
import {mapState, mapMutations, mapActions, mapGetters} from 'vuex'
export default{
name: 'Subtraction',
computed:{
...mapState(['count']),
...mapGetters(['showCount'])
},
methods:{
...mapMutations(['sub', 'subN']),
...mapActions(['subAsync', 'subNAsync']),
handlesub(){
this.sub()
},
sub3(){
this.subN(3)
},
handlesubAsync(){
this.subAsync()
},
sub3Async(){
this.subNAsync(3)
}
}
}
</script>
<style>
</style>