Vuex是什么
概念:Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。适用于任意组件之间通信。
PS:集中式(可以理解为学生都在课堂,老师给他们上课),还有分布式(可以理解为老师会72变,变成N个人,去学生家里给每个学生上课)
什么时候使用Vuex
如果您不打算开发大型单页应用,使用 Vuex 可能是繁琐冗余的。
那么当我们开大大型单页面组件的时候,一定要用Vuex吗?
- 当多个组件依赖于同意状态
- 当来自不同组件的行为需要改变同一状态
Vuex图解
来自于官方
Vuex的store中都有啥
- state:存储公共数据的
- mutations:操作公共数据的
- actions:触发mutations的(这一步在某些时候不需要,可以直接调用mutations里面的方法)
- getters:基于state中的数据再做处理的(可以理解为store的计算属性)
Vuex中的map系列
// 这两个是当我们这个页面使用不止一个store中的数据的时候,可以使用
import {mapState,mapGetters,mapMutations,mapActions} from 'vuex'
methods: {
increase() {
// this.$store.dispatch('increase',this.val)
// 如果没有复杂的逻辑,例如调用接口,我们可以直接接调用commit,不需要dispatch
this.$store.commit('INCREASE',this.val)
},
// 这样就可以直接使用了,不用像上面样的自己写方法调用,这样是直接调用的commit,不经过actions,同样有数组的写法,名称保持统一
...mapMutations({increase1:'INCREASE'}),
// 这样就可以直接使用了,不用像上面样的自己写方法调用,调用actions,同样有数组的写法,名称保持统一
...mapActions({increase2:'increase'})
},
computed:{
// 这是对象写法
// ...mapState({sum:'sum',userId:'userId',userName:'userName'}),
// ...mapGetters({bigSum:'bigSum'})
// 这是数组写法,这种写法,名字和store必须要一样
...mapState(['sum','userId','userName']),
...mapGetters(['bigSum'])
}
demo
// store/index.js
// 引入Vuex
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
// 创建state--用于存储数据
const state = {
sum: 0,
userId: 12345678,
userName: '景天'
}
// 创建mutations--用于操作数据(state)
const mutations = {
INCREASE(state,value) {
state.sum += value
},
DECREASE(state,value) {
state.sum -= value
}
}
// 创建actions--用于响应组件中的动作
// 如果调用的是store.dispatch来修改store里面的值,会触发这个,再触发mutations里面的方法
const actions = {
// 接收两个参数
// 第一个参数可以理解为是一个小型的store,可以获取和使用store身上的东西,第二个参数是你传进来的值
increase(context,value) {
// INCREASE这个大写不大写无所谓,只是有些人喜欢区分
context.commit('INCREASE',value)
},
decrease(context,value) {
// INCREASE这个大写不大写无所谓,只是有些人喜欢区分
context.commit('DECREASE',value)
}
}
// 基于state中的数据做处理
const getters = {
bigSum(state) {
return state.sum * 10
}
}
// 导出使用
export default new Vuex.Store({
state,
actions,
mutations,
getters
})
两个组件演示Vuex
// 组件1
<template>
<div class="increase">
<div>当前的和为:{{sum}}</div>
<div>显示10倍值:{{bigSum}}</div>
<select v-model.number="val">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
<button @click="increase">+</button>
<!-- 下面这一行传值进去是给mapMutations使用的,不然mapMutations获取不到你的值 -->
<button @click="increase1(val)">mapMutations的+</button>
<!-- 下面这一行传值进去是给mapActions使用的,不然mapActions获取不到你的值 -->
<button @click="increase2(val)">mapActions的+</button>
</div>
</template>
<script>
// 这几个是当我们这个页面使用不止一个store中的数据的时候,可以使用
import {mapState,mapGetters,mapMutations,mapActions} from 'vuex'
export default {
data() {
return {
val: 1
}
},
methods: {
increase() {
// this.$store.dispatch('increase',this.val)
// 如果没有复杂的逻辑,例如调用接口,我们可以直接接调用commit,不需要dispatch
this.$store.commit('INCREASE',this.val)
},
// 这样就可以直接使用了,不用像上面样的自己写方法调用,这样是直接调用的commit,不经过actions,同样有数组的写法,名称保持统一
...mapMutations({increase1:'INCREASE'}),
// 这样就可以直接使用了,不用像上面样的自己写方法调用,调用actions,同样有数组的写法,名称保持统一
...mapActions({increase2:'increase'})
},
// computed中的这些其实可以不用,只是你写的时候要写很多,这里相当于是优化代码
computed:{
// 设定一个值接收store中的值,这样就不用写一大串了
// 这是对象写法
// ...mapState({sum:'sum',userId:'userId',userName:'userName'}),
// ...mapGetters({bigSum:'bigSum'})
// 这是数组写法,这种写法,名字和store必须要一样
...mapState(['sum','userId','userName']),
...mapGetters(['bigSum'])
}
};
</script>
<style>
.increase {
background-color: #ccc;
}
</style>
// 组件2
<template>
<div class="decrease">
<div>当前的和为:{{$store.state.sum}}</div>
<div>显示10倍值:{{$store.getters.bigSum}}</div>
<select v-model.number="val">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
<button @click="decrease">-</button>
</div>
</template>
<script>
export default {
data() {
return {
val: 1
}
},
methods: {
decrease() {
// this.$store.dispatch('decrease',this.val)
this.$store.commit('DECREASE',this.val)
}
}
};
</script>
<style>
.decrease {
background-color: #eee;
}
</style>
复杂demo
实际业务中,可能会有很多模块,那么同样会有很多的state,mutations,所以,就有了分块的写法
// store/index.js
// 引入Vuex
import Vue from 'vue'
import Vuex from 'vuex'
import user from './modules/user'
import module1 from './modules/module1' // 这个里面的配置和user一样,只是业务逻辑的区别
Vue.use(Vuex)
// 导出使用
export default new Vuex.Store({
modules: {
user: user,
module1: module1
}
})
// ./modules/user
export default {
namespaced: true, // 不写不能直接使用名称
state: {
sum: 0,
userId: 12345678,
userName: '景天'
},
mutations: {
INCREASE(state,value) {
state.sum += value
},
DECREASE(state,value) {
state.sum -= value
}
},
actions: {
increase(context,value) {
context.commit('INCREASE',value)
},
decrease(context,value) {
context.commit('DECREASE',value)
}
},
getters: {
bigSum(state) {
return state.sum * 10
}
}
}
同样两个组件演示
// 组件1
<template>
<div class="increase">
<div>当前的和为:{{sum}}</div>
<div>显示10倍值:{{bigSum}}</div>
<select v-model.number="val">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
<button @click="increase">+</button>
<!-- 下面这一行传值进去是给mapMutations使用的,不然mapMutations获取不到你的值 -->
<button @click="increase1(val)">mapMutations的+</button>
<!-- 下面这一行传值进去是给mapActions使用的,不然mapActions获取不到你的值 -->
<button @click="increase2(val)">mapActions的+</button>
</div>
</template>
<script>
// 这几个是当我们这个页面使用不止一个store中的数据的时候,可以使用
import {mapState,mapGetters,mapMutations,mapActions} from 'vuex'
export default {
data() {
return {
val: 1
}
},
methods: {
increase() {
// this.$store.dispatch('user/increase',this.val)
this.$store.commit('user/INCREASE',this.val)
},
...mapMutations('user',{increase1:'INCREASE'}),
...mapActions('user',{increase2:'increase'})
},
computed:{
...mapState('user',{sum:'sum',userId:'userId',userName:'userName'}),
...mapGetters('user',{bigSum:'bigSum'})
// ...mapState('user',['sum','userId','userName']),
// ...mapGetters('user',['bigSum'])
}
};
</script>
<style>
.increase {
background-color: #ccc;
}
</style>
// 组件2
<template>
<div class="decrease">
<div>当前的和为:{{$store.state.user.sum}}</div>
<!-- modules模式下的getters,需要这么获取值 -->
<div>显示10倍值:{{$store.getters['user/bigSum']}}</div>
<select v-model.number="val">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
<button @click="decrease">-</button>
</div>
</template>
<script>
export default {
data() {
return {
val: 1
}
},
methods: {
decrease() {
// this.$store.dispatch('user/decrease',this.val)
this.$store.commit('user/DECREASE',this.val)
}
}
};
</script>
<style>
.decrease {
background-color: #eee;
}
</style>
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。