Vuex
Vuex是实现组件全局状态(数据)管理的一种机制,可以方便的实现组件之间的数据共享
Vuex的优势
- 能够在vuex中集中管理数据,易于开发和后期维护
- 能够高效实现组件之间的数据共享,提高开发效率
- 存储在vuex中的数据都是响应式的,能够实时保持数据于页面的同步
开始
- 安装vuex依赖包
npm install vuex --save
- 导入vuex包
- 挂载到上
- 创建一个vuex.store实例
- 挂载到vue实例中Code
1
2
3
4
5
6
7
8
9import Vuex from "vuex";
Vue.use(Vuex);
let store = new Vuex.Store({});
let vm = new Vue({
store
})
State
State提供唯一的公共数据源,所有共享的数据都要统一放到Store的State中进行存储
使用state的两种方式
- 使用
this.$store.state
来获取全局的数据 - 使用
mapState
mapState辅助函数
当一个组件获取多个状态的时候,将这些状态都声明为计算属性会有写复杂和冗余,为了解决这个问题,我们可以使用mapState
辅助函数帮助我们生成计算属性
1 | import { mapState } from "vuex" |
对象展开运算符
mapState
函数返回的是一个对象,我们可以使用对象展开运算符极大简化写法:
1 | computed: { |
Mutation
Mutation用于同步变更Store中的数据
- 在vuex中只能通过mutation变更Store数据,不可以直接操作Store中的数据
this.$store.state.data++
这种方式虽然不报错,但是不能这么使用
- 通过这种方式虽然操作起来稍微繁琐一些,但是可以集中监控所有数据的变化
- 定义的函数只能传两个参数
- state对象
- 调用方法传过来的参数
使用mutations的两种方式
- 通过this.$store.commit来调用Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14// 定义全局方法
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
add(state,step){
state.count = state.count++
}
}
})
// 调用
this.$store.commit("add",3) - 通过mapMutation来调用Code
1
2
3
4
5
6
7
8
9
10
11// 从vuex中按需导入mapMutations函数
import { mapMutations } from "vuex";
通过刚才导入的mapMutations函数,将需要的mutations函数,映射为当前组件的methods方法
methods: {
...mapMutations(["add"]),
addButton(){
this.add(3);
}
}
只有mutations才有权力对数据进行修改,actions中也需要调用mutations中的函数
注意:在mutations声明的方法不能有异步的代码,不然调式工具检测不到,如果想使用异步操作,则需要使用Action
Action
Action用于处理异步操作数据
如果通过异步操作变更数据,必须通过Action,而不是使用mutations,但是在Action中还是要通过触发mutation的方式间接变更数据
这里传参就很麻烦,需要一层层传递下去
使用actions的两种方式
- this.$store.dispatch()Javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20const store = new Store({
mutations: {
add(state,step){
state.count+= step
}
},
actions: {
addAsync(context,step){ // 接收参数传递下去
setTimeout(()=>{
context.commit("add",step) // 接收参数传递下去
},1000)
}
}
})
methods: {
handle(){
this.$store.dispatch("addAsync",3) // 传入实参
}
} - 使用mapActionsJavascript
1
2
3
4
5
6
7// 按需导入mapActions
import { mapActions } from "vuex";
// 通过刚才导入的mapActions函数,将需要的actions函数,映射为当前组件的methods方法
methods: {
...mapActions(["addAsync"])
}
应用场景:
当看到这里时,你会觉得好像跟mutation
是一样的,再mutation
中异步操作也不会报错结果也正常,那么是不是action
是不是就没意义了,下面的场景能证明一下下存在的意义
- 创建了两个异步操作
- 第二个操作依赖于第一个操作的值
- 如果第二个先执行那么结果肯定是报错的(这里借助Promise)
感觉其实也没啥区别,方正也易于后期维护代码把
getters
getter用于对Store中的数据进行加工处理形成新的数据
应用场景:给数据添加其他的文字
- getter可以对Store中已有的数据加工处理从而形成新的数据,类似Vue的计算属性
- Store中的数据发生变化,getter的数据也会跟着变化
使用getter的两种方式
this.$store.getters
Javascript1
2
3
4
5
6
7
8
9
10
11
12const store = new Vuex.Store({
state: {
count: 0
},
getters: {
showNum(state,getters){ // 第一个参数是当前的state,第二个是当前getters中的所有属性
return `当前最新的数量是${state.count}`
}
}
})
<p>{{$store.getters.showNum}}</p>- 通过mapGettersCode
1
2
3
4
5import { mapGetters } from "vuex";
computed: {
...mapGetters(["showNum"])
}
通过方法访问
你也可以通过让 getter 返回一个函数,来实现给 getter 传参。在你对 store 里的数组进行查询时非常有用。
1 | getters: { |
modules
对数据的分块管理,解决命名冲突等问题,模块化
使用的两种方式:
- this.$store.state.module.state名Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15const module1 = new Vuex.Store({
state: { name: "zyt" }
})
const module2 = new Vuex.Store({
state: { name: "zrb" }
})
const store = new Vuex.Store({
modules: {module1,module2}
})
<p>{{$store.state.module1.name}}</p>
<p>{{$store.state.module2.name}}</p> - 通过mapStateCode
1
2