共计 5909 个字符,预计需要花费 15 分钟才能阅读完成。
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> |
正文完