Vue

Vue组件通信之VueX

解决非关系型组件间数据传递,数据通信,数据共享的工具!

Posted by AzirKxs on 2022-10-11
Estimated Reading Time 7 Minutes
Words 1.7k In Total
Viewed Times

Vue组件通信之VueX

组件间通信的几种情况

组件通信

以上的几种情况都可以依靠现有的技术解决,但是当我们遇到非关系型组件之间需要进行数据传递,数据通信,数据共享的时候,这时候采用上面的技术就会非常复杂,且不易维护,因此我们需要使用vuex来解决非关系型组件的数据共享。

VueX简介

VueX是采用集中式管理组件依赖的共享数据的一个工具,可以解决不同组件的数据共享问题

vuex

  • state:存放共享状态数据

  • mutations:修改state,需要修改state只能通过mutations,且只能执行同步代码

  • actions:完成异步操作,将数据提交给mutations进行修改

VueX的初始化

安装

1
npm install vuex -S #运行时依赖

引入并调用

在main.js中

1
2
import Vuex from 'vuex';
Vue.use(vuex);

完成实例化

1
2
3
const store = new vuex.Store({
//实例化vuex的构造参数 state,mutations,actions
}); //实例化一个Vuex

挂载到根节点

1
2
3
4
new Vue({
el:'#app',
store:store
})

VueX之state

实例化state

1
2
3
4
5
6
7
const store = new vuex.Store({
//实例化vuex的构造参数 state,mutations,actions
state:{
//需要存储的状态
count:0;
}
}); //实例化一个Vuex

组件引用state

原始引用
1
<p>{{$store.state.count}}</p>
计算属性
1
2
3
4
5
computed:{
count(){
return this.$store.state.count;
}
}
1
<p>{{count}}</p>
辅助形式
  • 引入mapState
1
import {mapState} from 'vuex';
  • 使用
1
2
3
computed:{
...mapState(['count']);//利用延展运算符将数组放入computed
}
1
<p>{{count}}</p>

VueX之mutations

一次mutation的执行,立刻得到一种视图状态,因为是立刻,所以必须是同步代码,不能执行异步代码,因为同步总是先于异步执行

定义mutations

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
const store = new vuex.Store({
//实例化vuex的构造参数 state,mutations,actions
state:{
//需要存储的状态
count:0,
},
mutations:{
//修改state的mutation方法
//每一个mutation都有对应的参数
addCount(state,payload=1){
//state:指的是当前vuex中的state对象
//payload:载荷提交mutation方法的时候传递的参数,可以不传
state.count+=payload;
}
}
}); //实例化一个Vuex

调用mutations

原始形式
1
2
<p>{{count}}</p>
<button @click='add'>点我+1</button>
1
2
3
4
5
6
7
methods:{
add(){
//调用mutation方法,完成一次提交
//commit(方法名称,携带的参数payload)
this.$store.commit("addCount",10);
}
}
辅助形式
  • 导入
1
import {mapMutation} from 'vuex';
  • 使用
1
2
3
methods:{
...mapMutations(['addCount']);
}
1
<button @click='addCount(100)'>点我+100</button><!--100就是载荷  -->

VueX之actions

mutations只能执行同步代码,因此需要actions先执行异步代码进行一些异步动作处理数据

定义actions

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
const store = new vuex.Store({
//实例化vuex的构造参数 state,mutations,actions
state:{
//需要存储的状态
count:0,
},
mutations:{
//修改state的mutation方法
//每一个mutation都有对应的参数
addCount(state,payload=1){
//state:指的是当前vuex中的state对象
//payload:载荷提交mutation方法的时候传递的参数,可以不传
state.count+=payload;
}
},
//进行一些异步动作处理数据
actions:{
//方法
//action方法桉树
//context:执行的上下文对象,相当于组件中的this.$store
getAsyncCount(context,params){
setTimeOut(function(){
context.commit("addCount",100);//调用一个mutation方法
},3000)
}
}
}); //实例化一个Vuex

调用actions

原始形式
1
<button @click='test'>点我+1</button>
1
2
3
4
5
methods:{
test(){
this.$store.dispatch('getAsyncCount',100);
}
}
辅助形式
  • 引入
1
import {mapActions} from 'vuex';
  • 使用
1
2
3
methods:{
...mapActions(['getAsyncCount']);
}
1
<button @click='getAsyncCount(100)'>点我+1</button>

VueX之getters

除了state之外,有时我们还需要从state中派生出一些状态,此时会用到getters,getters为vuex的计算属性

定义getters

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
const store = new vuex.Store({
//实例化vuex的构造参数 state,mutations,actions
state:{
//需要存储的状态
count:0,
list:[1,2,3,4,5,6,7,8,9,10]
},
mutations:{
//修改state的mutation方法
//每一个mutation都有对应的参数
addCount(state,payload=1){
//state:指的是当前vuex中的state对象
//payload:载荷提交mutation方法的时候传递的参数,可以不传
state.count+=payload;
}
},
//进行一些异步动作处理数据
actions:{
//方法
//action方法桉树
//context:执行的上下文对象,相当于组件中的this.$store
getAsyncCount(context,params){
setTimeOut(function(){
context.commit("addCount",100);//调用一个mutation方法
},3000)
}
},
getters:{
filterList:function(state){
return state.list.filter(item=>item>5);
}
}
}); //实例化一个Vuex

调用getters

原始形式
1
2
3
<p>
{{$store.getters.filterList}}<!--[6,7,8,9,10] -->
</p>
辅助形式
  • 导入
1
import {mapGetters} from 'vuex';
  • 调用
1
2
3
computed:{
...mapGetters('filterList');
}
1
2
3
<p>
{{filterList}}<!--[6,7,8,9,10] -->
</p>

VueX的模块化

当一个vuex中的数据多到难以维护时,我们可以对它进行拆分

vuex模块化

定义多个模块

1
2
3
4
5
6
7
8
9
10
11
12
13
14
const store = new vuex.Store({
modules:{
user:{
state:{
name:'azirkxs'
}
},
setting:{
state:{
theme:'dark'
}
}
}
}); //实例化一个Vuex

上面分别定义了user和setting模块,每个模块内部都有对应的state,mutations,actions和getters

1
2
<p>{{$store.state.user.name}}</p><!-- azirkxs -->
<p>{{$store.state.setting.theme}}</p><!-- dark -->

通过getters简化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
const store = new vuex.Store({
modules:{
user:{
state:{
name:'azirkxs'
}
},
setting:{
state:{
theme:'dark'
}
}
},
getters:{
name:state=>state.user.name,
theme:state=>state.setting.theme
}
}); //实例化一个Vuex
1
2
3
computed:{
...mapGetters(['name','theme']);
}
1
2
3
<p>
{{name}}:{{theme}}
</p>

模块化中的命名空间

默认情况下,模块内部的action,mutation和getter是注册在全局命名空间的,仍然可以用过全局调用的方式调用,此时如果不想通过全局调用的方式调用,可以为模块设置namespaced属性为true,这时会通过模块名称/方法名称的方式绑定到store对象对应的属性中,调用方法时需要提供路径

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
const store = new vuex.Store({
modules:{
user:{
namespaced:true,
state:{
name:'azirkxs'
},
mutations:{
say(state){
console.log(state);
}
}
},
setting:{
namespaced:true,
state:{
theme:'dark'
}
}
},
getters:{
name:state=>state.user.name,
theme:state=>state.setting.theme
}
}); //实例化一个Vuex
1
2
3
4
5
6
7
methods:{
say(){
//调用mutation方法,完成一次提交
//commit(方法名称,携带的参数payload)
this.$store.commit("user/print");
}
}
1
2
3
<button @click="say">
点击说出自己的名字
</button>

如果这篇文章对你有帮助,可以bilibili关注一波 ~ !此外,如果你觉得本人的文章侵犯了你的著作权,请联系我删除~谢谢!