一:前言
1.1 Vuex 是什么?
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
1.2 vuex核心概念
vuex是存储组件数据的集中式的仓库(如何优雅的读写仓库中的数据)
-
state:仓库内存数据的配置
-
getters:仓库内的计算属性
-
action:操作数据的工具
-
mutation:操作数据的工具
1.3 安装命令
npm install vuex -save
二:简单使用
2.1 main.js引用vuex
// VueX 引用
import Vuex from 'vuex'
Vue.use(Vuex);
//真实开发会在src下独立创建store文件夹,编写逻辑代码
2.2 创建store
src下独立创建store文件夹
store文件夹中创建index.js
index.js完整代码
// 引入Vue核心库
import Vue from 'vue'
// 引入Vuex
import Vuex from 'vuex'
// 应用插件
Vue.use(Vuex)
// 创建对象
const store = new Vuex.Store({
// 准备actions对象——响应组件中用户的动作
actions: {},
// 准备mutations对象——修改state中的数据
mutations:{},
// 准备state对象——保存具体的数据
state: {
count:0,
sum: 666,
},
getters: {},
modules: {}
})
export default store;
2.3 main.js导入store
// 将刚才引用的vuex注释或者删除 直接用store中引用
// import Vuex from 'vuex'
// Vue.use(Vuex);
import store from './store'
new Vue({
el:'#app',
store, //在这里才能通过原型链让所有组件通过$store用到
render:h => h(App)
})
2.3 读取state里设置的值
<div>
{{$store.state.sum}}
</div>
三:Vuex核心概念
3.1 mutation的使用
-
只有通过mutation才能更改state中变量的值
-
例如:将state中count加任意数
store文件夹中index.js文件
mutations:{
// 执行加传入的参数
JIA (state, value) {
// console.log('mutations中的JIA被调用了', state, value)
state.count += value
},
}
任意vue文件代码
<template>
<div>
<h1>{{$store.state.count}}</h1>
<el-button @click="test()">测试</el-button>
</div>
</template>
<script>
export default {
name: 'store',
methods: {
test(){
// 会改变count 默认值
this.$store.commit("JIA",10)
}
}
}
</script>
点击前 点击后
3.2 getters的使用
- getters可以理解为store中的计算属性,对state中的变量在输出前进行处理。
- 例如:需要实现再点击降数值乘10,就可以在getters.js添加以下代码
store文件夹中index.js文件
getters: {
bigSum (state) {
return state.sum * 10
},
},
任意vue文件代码
<template>
<div>
<el-button @click="test()">测试</el-button>
</div>
</template>
<script>
export default {
name: 'store',
methods: {
test(){
// 调用getters中的bigSum将默认值sum=1×10后返回
//不会改变sum默认值
console.log(this.$store.getters.bigSum)
}
}
}
</script>
控制台输出结果
3.3 actions的使用
- mutations中只能是同步操作,但是在实际的项目中,会有异步操作
- Action 提交的是 mutation,而不是直接变更状态。
- Action 可以包含任意异步操作。
store文件夹中index.js文件
actions: {
// 响应组件中加的动作
jia (context, value) {
// console.log('actions中的jia被调用了', value)
setTimeout(() => {
context.commit('JIA', value)
}, 1000)
}
}
任意vue文件代码
<template>
<div>
<h1>{{$store.state.count}}</h1>
<el-button @click="test()">测试</el-button>
</div>
</template>
<script>
export default {
name: 'store',
methods: {
test(){
console.log(this.$store.dispatch('jia',5))
}
}
}
</script>
3.4 module的使用
- 由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。
- 当应用变得非常复杂时,store 对象就有可能变得相当臃肿。
- 为了解决以上问题,Vuex 允许我们将 store 分割成模块(module)。
- 每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割。
const moduleA = {
state: () => ({ ... }),
mutations: { ... },
actions: { ... },
getters: { ... }
}
const moduleB = {
state: () => ({ ... }),
mutations: { ... },
actions: { ... }
}
const store = createStore({
modules: {
a: moduleA,
b: moduleB
}
})
store.state.a // -> moduleA 的状态
store.state.b // -> moduleB 的状态
四:辅助函数
4.1 mapState 辅助函数
当一个组件需要获取多个状态的时候,通过this.$store.state来声明就会显得有些重复跟冗余,通过mapState这个辅助函数可以帮助生成计算属性。
//在组件中使用mapState,放置在computed里面。
//项目中常用的方式
import { mapState } from 'vuex'
export default{
computed:{
// 在组件通过this.变量名就可调用, 不用再写this.$store.state.变量名
...mapState(['num','count'])
}
}
4.2 mapGetters辅助函数
<template>
{{bigSum}}
</template>
import {mapGetters} from 'vuex'
computed:{
//直接this.bigSum 调用
...mapGetters(['bigSum']) // == this.$store.getters.bigSum
}
4.3 mapMutations辅助函数
<template>
<div>
<h1>{{count}}</h1>
<el-button @click="JIA(10)">测试</el-button>
</div>
</template>
<script>
import { mapState,mapMutations} from 'vuex'
export default {
name: 'store',
computed:{
// 在组件通过this就可调用,不用再写this.$store.state
...mapState(['count',]),
}
methods: {
//this.JIA() 为 this.$store.commit('JIA')
...mapMutations(['JIA']),
}
}
</script>
4.4 mapActions辅助函数
<template>
<div>
<h1>{{count}}</h1>
<el-button @click="jia(10)">测试</el-button>
{{bigSum}}
</div>
</template>
<script>
import { mapState,mapActions} from 'vuex'
export default {
name: 'store',
computed:{
// 在组件通过this就可调用,不用再写this.$store.state
...mapState(['count',]),
},
methods: {
// 映射 this.jia() 为 this.$store.dispatch('jia')
...mapActions(['jia','changeNumber2Action']),
}
}
</script>