Note1- Vuex
目录1.vuex
vuex的状态管理功能主要解决了Vue组件间的通信问题吗,让夸层级共享数据或平级组件共享数据变得非常容易。
2.关于状态管理
2.1 状态数据
状态数据是指data函数中返回的数据,这些数据自带响应性,由其来对视图的展现进行驱动的
2.2 视图
视图是指template里面定义的视图模板,其通过声明的方式将状态映射到视图上
2.3 动作
动作就是指会引起状态变化的行为,即上面的methods选项中定义的方法,这些方法用来改变状态数据,状态数据的改动最终驱动视图的刷新
上面3部分的协同工作就是Vue状态管理的核心。总体来看,在这个状态管理模式中,数据的流向是单向的、私有的。由视图触发动作,由动作改变状态,由状态驱动视图。
对于组件不多简介的vue应用来说,这种模式非常高效,但是对于多组件复杂交互的场景,使用这种方式进行状态管理就会比较困难。
- 有多个组件依赖于同一状态
- 多个组件都可能触发动作变更一个状态
(普通的做法共享一个状态是非常困难的)
vuex就是基于这种应用场景产生的,在vuex中,可以将需要组件间共享的状态抽取出来,以一个全局的单例模式进行管理。在这种模式下,视图无论在视图树中的哪个位置,都可以直接获取这些共享的状态,也可以直接触发修改动作来动态改变这些共享的状态
3.安装Vuex
npm install vuex@next --save
基本的vuex使用如下:
import { createStore } from 'vuex';
//vuex
const store = createStore({
state() {
return {
count: 1
}
},
mutations: {
increment(state) {
state.count++;
}
}
});
//app是vue的实例
app.use(store);
<template>
<div>
<p>
<span> 计数器1(state):{{this.$store.state.count}}</p>
<p><button @click="increment">增加</button></p>
</div>
</template>
<script>
export default {
data() {
return {
count:0
}
},
methods: {
increment(){
this.$store.commit('increment');
}
},
}
</script>
4.vuex中的一些核心概念
vuex中5个核心的概念:state、getter、mutation、action和module
4.1 vuex中的状态state
状态实际上就是应用中组件需要共享的数据。在Vuex中采用单一状态树来存储状态数据,也就是说我们的数据源是唯一的。在任何组件中,都可以使用如下方式来获取任何一个状态树中的数据:
this.$store.state
Vuex也提供了mapState方法来将其直接映射成组件中的计算属性进行使用,由于状态数据本省具有响应性,因此将其映射为计算属性后也具有响应性,使用计算属性和直接使用状态数据并无不同
代码:
使用
<template>
<div>
<p>
<hr/>
{{countData3}}
</p>
<p><button @click="increment">增加</button></p>
</div>
</template>
<script>
import { mapGetters } from 'vuex';
export default {
data() {
return {
count:0
}
},
methods: {
increment(){
this.$store.commit({type:'increment3',count:2});
}
},
computed:mapState({
//通过字符串映射
countData:'count',
//通过函数映射
conutData2(state){
return state.count;
},
countData3(state){
//分模块时的模块调用
return state.moduleDemo1.count1;
}
})
}
</script>
配置
//vuex
const store = createStore({
state() {
return {
count: 1
}
},
mutations: {
increment(state) {
state.count++;
}
}
});
app.use(store);
app.mount("#app");
4.2 vuex中的Getter方法
在vue中,计算属性实际上就是Getter方法,当我们需要将数据处理过再进行使用时,就可以使用计算属性。对vuex来说,借助mapState方法,可以方便地将状态映射为计算属性,从而增加一些所需的业务逻辑。但如果有些计算属性是通用的,或者这些计算属性也是多组件共享的,此时在这些组件中都实现一遍这些计算方法就显得非常多余。Vuex允许我们在定义state实例时添加一些仓库本身的计算属性,即Getter方法
示例代码:
//vuex
const store = createStore({
state() {
return {
count: 1
}
},
mutations: {
increment(state) {
state.count++;
}
},
getters: {
countText(state) {
return state.count + "次";
}
}
});
调用:
方式1
计数器1(使用getters对state进行修改操作):{{this.$store.getters.countText}}
方式2
computed:mapGetters(['countText'])
Getter方法也支持参数传递
getters: {
countText(state) {
return (s) => {
return state.count + s;
}
}
}
this.$store.getters.countText('次')
4.3 vuex中的Mutation
在Vuex中,修改store中的某个状态数据的唯一方法是提交Mutation。Mutation的定义非常简单,我们只需要将数据变动的行为封装成函数,配置在store实例的mutations选项中即可。在前面编写的示例代码中,我们曾使用Mutation来触发计数器数据的自增,定义的方法如下:
mutations: {
increment(state) {
state.count++;
}
},
调用
this.$store.commit(‘increment’);
将对象作为参数
mutations: {
//接收参数
increment2(state, n) {
state.count += n;
},
//将对象作为参数
increment3(state, payload) {
state.count += payload.count;
}
}
this.$store.commit({
type:"moduleDemo1/increment",
count:1
})
4.4 vuex中的Action
Action是我们将要接触到的一个新的Vuex中的核心概念。我们知道,要修改store仓库中的状态数据,需要通过提交Mutable来实现。但是Mutation有一个很严重的问题;其定义的方法必须是同步的,即只能同步地对数据进行修改。在实际开发中,并非所有修改数据的场景都是同步的,例如从网络请求获取数据,之后刷新页面。当然,也可以将异步的操作放到组件内部外理,异步操作结束后再提交修改到store仓库,但这样可能合使本来可以复用的代码要在多个组件中分别编写一遍。Vuex中提供了Action来处理这种场景。
Action与Mutation类似,不同的是,Action并不会直接修改状态数据,而是对Mutation进行包装,通过提交Mutation来实现状态的改变。这样在Action定义的方法中,允许我们包含任意的一步操作。
const store = createStore({
state() {
return {
count: 1
}
},
mutations: {
increment3(state, payload) {
state.count += payload.count;
}
},
actions: {
asyncIncrement(context, payload) {
setTimeout(() => {
context.commit('increment3', payload);
}, 3000);
}
}
});
在组件中使用Action,需要通过store实例对象的dispatch方法来触发
计数器1(actions异步调用):{{this.$store.dispatch('asyncIncrement',{count:3})}}
对于Action来说,其允许异步操作,但是并不是说其必须进行异步操作,在Action中也可以定义同步的方法,只是在这种场景下,其与Mutation的功能完全一样。
4.5 vuex中的Module
Module是Vuex进行模块化编程的一种方式。前面我们分析过,在定义store仓库时,无论是其中的状态,还是Mutation和Action行为,都是共享的,可以将其理解为通过store单例来统一管理。
在这种情形下,所有的状态都会集中到同一个对象中,虽然使用起来并没有什么问题,但是过于复杂的对象会使阅读和维护变得困难。为了解决此问题,Vuex中引入了Module模块的概念。
Vuex允许我们将store分割成模块,每个模块拥有自己的state、mutations、actions、getters,甚至可以嵌套拥有自己的子模块。
//vuex模块划分
const module1 = {
//Vuex模块化的本意是store进行拆分和隔离。你可能已经发现了,目前虽然模块中的状态数据进行了隔离,但是实际上Mutation依然是共用的,在触发Mutation的时候,也没有进行模块的区分,如果需要更高的封装度与复用性,可以开启模块的命名空间功能,这样模块内部的Getter、Action以及Mutation都会根据模块的嵌套路径进行命名,实际上实现了模块间的完全隔离。例如修改模块
namespaced: true,
state() {
return {
count1: 7
}
},
mutations: {
increment(state, payload) {
state.count1 += payload.count;
}
}
};
const module2 = {
namespaced: true,
state() {
return {
count2: 0
}
},
mutations: {
increment(state, payload) {
state.count2 += payload.count;
}
}
}
//vuex
const store = createStore({
modules: {
module1,
module2
}
});
模块数据和方法调用方式
this.$store.commit({
type:"moduleDemo1/increment",
count:1
})
computed:mapState({
countData3(state){
return state.moduleDemo1.count1;
}
})
计数器2:{{this.$store.state.moduleDemo1.count1}}
模块动态注册
//vuex动态注册module
store.registerModule("moduleDemo1", module1);
总结
Vuex的状态管理功能主要解决了vue组件间的通信问题,让跨层级共享数据或平级组件共享数据变得非常容易
标签:count,状态,Vue,系列,vuex,state,Vuex,store From: https://www.cnblogs.com/caiiac/p/16819056.html