1、Vuex概述
Vuex是实现组件全局状态(数据)管理的一种机制,可以方便的实现组件之间的数据共享
使用Vuex管理数据的好处:
- 能够在Vuex中集中管理共享的数据,便于开发和后期进行维护
- 能够高效的实现组件之间的数据共享,提高开发效率
- 存储在Vuex中的数据是响应式的,当数据发生改变时,页面中的数据也会同步更新
什么样的数据适合存储到Vuex中:
一般情况下,只有组件之间共享的数据,才有必要存储到Vuex中;对于组件中的私有数据,依旧存储在组件自身的data中即可
2、Vuex的基本使用
1)、安装vuex依赖包
npm install vuex --save
2)、导入vuex包
import Vuex from 'vuex'
Vue.use(Vuex)
3)、创建store对象
export default new Vuex.Store({
//state中存放的就是全局共享的数据
state: {
},
mutations: {
},
actions: {
},
modules: {
}
})
4)、将store对象挂载到vue实例中
new Vue({
//将创建的共享数据对象,挂载到vue实例中
//所有的组件就可以直接从store中获取全局的数据了
store,
render: h => h(App)
}).$mount('#app')
3、Vuex中的核心特性
1)、State
State提供唯一的公共数据源,所有共享的数据都要统一放到Store中的State中存储
在State对象中可以添加要共享的数据,如:count:0
export default new Vuex.Store({
state: {
count: 0
},
mutations: {
},
actions: {
},
modules: {
}
})
在组件中访问State的方式:
方式一:
this.$store.state.全局数据名称
,如:this.$store.state.count
<template>
<div>
<h3>当前最新的count值为:{{$store.state.count}}</h3>
<button>+1</button>
</div>
</template>
方式二:
先按需导入mapState函数:import { mapState } from 'vuex'
然后数据映射为计算属性:computed:{ ...mapState(['全局数据名称']) }
<template>
<div>
<h3>当前最新的count值为:{{count}}</h3>
<button>-1</button>
</div>
</template>
<script>
import { mapState } from 'vuex'
export default {
data () {
return {}
},
computed: {
...mapState(['count'])
}
}
</script>
2)、Mutation
Mutation用于修改变更$store中的数据
- 只能通过mutation变更Store数据,不可以直接操作Store中的数据
- 通过这种方式虽然操作起来稍微繁琐一些,但是可以集中监控所有数据的变化
定义Mutation:
export default new Vuex.Store({
state: {
count: 0
},
mutations: {
add (state, step) {
// 第一个形参永远都是state也就是$state对象
// 第二个形参是调用add时传递的参数
state.count += step
}
},
actions: {
},
modules: {
}
})
在组件中触发Mutation:
方式一:
<template>
<div>
<h3>当前最新的count值为:{{count}}</h3>
<button @click="btnHandler">+1</button>
</div>
</template>
<script>
import { mapState } from 'vuex'
export default {
data () {
return {}
},
computed: {
...mapState(['count'])
},
methods: {
btnHandler () {
this.$store.commit('add', 1)
}
}
}
</script>
方式二:
<template>
<div>
<h3>当前最新的count值为:{{count}}</h3>
<button @click="btnHandler">-1</button>
</div>
</template>
<script>
import { mapState, mapMutations } from 'vuex'
export default {
data () {
return {}
},
computed: {
...mapState(['count'])
},
methods: {
// 获得mapMutations映射的sub函数
...mapMutations(['sub']),
// 当点击按钮时触发Sub函数
btnHandler () {
// 调用sub函数完成对数据的操作
this.sub(1)
}
}
}
</script>
3)、Action
Action用于处理异步任务。如果通过异步操作变更数据,必须通过Action,而不能使用Mutation,但是在Action中还是要通过触发Mutation的方式间接变更数据
方式一:
export default new Vuex.Store({
state: {
count: 0
},
mutations: {
add (state, step) {
// 第一个形参永远都是state也就是$state对象
// 第二个形参是调用add时传递的参数
state.count += step
},
sub (state, step) {
state.count -= step
}
},
actions: {
addAsync (context, step) {
setTimeout(() => {
// 在action中,不能直接修改state中的数据 必须通过context.commit()触发某个mutation才行
context.commit('add', step)
}, 1000)
}
},
modules: {
}
})
<template>
<div>
<h3>当前最新的count值为:{{count}}</h3>
<button @click="btnHandler">+1</button>
<button @click="btnHandler2">+1 Async</button>
</div>
</template>
<script>
import { mapState } from 'vuex'
export default {
data () {
return {}
},
computed: {
...mapState(['count'])
},
methods: {
btnHandler () {
this.$store.commit('add', 1)
},
btnHandler2 () {
this.$store.dispatch('addAsync', 1)
}
}
}
</script>
方式二:
export default new Vuex.Store({
state: {
count: 0
},
mutations: {
add (state, step) {
// 第一个形参永远都是state也就是$state对象
// 第二个形参是调用add时传递的参数
state.count += step
},
sub (state, step) {
state.count -= step
}
},
actions: {
addAsync (context, step) {
setTimeout(() => {
// 在action中,不能直接修改state中的数据 必须通过context.commit()触发某个mutation才行
context.commit('add', step)
}, 1000)
},
subAsync (context, step) {
setTimeout(() => {
context.commit('sub', step)
}, 1000)
}
},
modules: {
}
})
<template>
<div>
<h3>当前最新的count值为:{{count}}</h3>
<button @click="btnHandler">-1</button>
<button @click="btnHandler2">-1 Async</button>
</div>
</template>
<script>
import { mapState, mapMutations, mapActions } from 'vuex'
export default {
data () {
return {}
},
computed: {
...mapState(['count'])
},
methods: {
// 获得mapMutations映射的sub函数
...mapMutations(['sub']),
...mapActions(['subAsync']),
// 当点击按钮时触发Sub函数
btnHandler () {
// 调用sub函数完成对数据的操作
this.sub(1)
},
btnHandler2 () {
this.subAsync(1)
}
}
}
</script>
4)、Getter
Getter用于对Store中的数据进行加工处理形成新的数据。它只会包装Store中保存的数据,并不会修改Store中保存的数据,当Store中的数据发生变化时,Getter生成的内容也会随之变化
定义Getter:
export default new Vuex.Store({
state: {
count: 0
},
mutations: {
add (state, step) {
// 第一个形参永远都是state也就是$state对象
// 第二个形参是调用add时传递的参数
state.count += step
},
sub (state, step) {
state.count -= step
}
},
actions: {
addAsync (context, step) {
setTimeout(() => {
// 在action中,不能直接修改state中的数据 必须通过context.commit()触发某个mutation才行
context.commit('add', step)
}, 1000)
},
subAsync (context, step) {
setTimeout(() => {
context.commit('sub', step)
}, 1000)
}
},
getters: {
showNum (state) {
return '当前最新的数量是【' + state.count + '】'
}
},
modules: {
}
})
在组件中使用Getter:
方式一:
<template>
<div>
<h3>{{$store.getters.showNum}}</h3>
<button @click="btnHandler">+1</button>
<button @click="btnHandler2">+1 Async</button>
</div>
</template>
方式二:
<template>
<div>
<h3>{{showNum}}</h3>
<button @click="btnHandler">-1</button>
<button @click="btnHandler2">-1 Async</button>
</div>
</template>
<script>
import { mapState, mapMutations, mapActions, mapGetters } from 'vuex'
export default {
data () {
return {}
},
computed: {
...mapState(['count']),
...mapGetters(['showNum'])
},
methods: {
// 获得mapMutations映射的sub函数
...mapMutations(['sub']),
...mapActions(['subAsync']),
// 当点击按钮时触发Sub函数
btnHandler () {
// 调用sub函数完成对数据的操作
this.sub(1)
},
btnHandler2 () {
this.subAsync(1)
}
}
}
</script>