- A+
本人水平有限,如有疏漏或者不正确部分,请大佬指正。
一.Vuex概述
1.1组件之间共享数据的方式
父向子传值:v-bind 属性绑定
子向父传值:v-on 事件绑定
兄弟组件之间共享数据:eventBUs
* $on 接收数据的那个组件
* $emit 发送数据的那个组件
特点:适合小范围使用
1.2Vuex是什么
概念:Vuex是实现组建全局状态(数据)管理的一种机制,可以方便的实现组件之间数据的共享
1.3使用Vuex统一管理状态的好处
①:能够在vuex中集中管理共享的数据,易于开发和后期维护
②:能够高效地实现组件之间的数据共享,提高开发效率
③:储存在vuex中的数据都是响应式的,能够试试保持数据与页面的同步
1.4什么样的数据适合存储到Vuex中
一般情况下,只有组件之间共享的数据,才有必要存储到vuex中,对于组件中的私有数据,依旧存储在组件自身的data中即可。
二.Vuex的基本使用
1.安装vuex依赖包
npm install vuex --save
2.导入vuex包
import Vuex from 'vuex'
Vue.use(Vuex)
3.创建store对象
const store =new Vuex.Store({
//state 中存放的就是全局共享的数据
state:{ count : 0}
})
4.将store 对象挂载到vue实例中
new Vue({
el:"#app",
render:h => h(app),
router,
store
})
三.Vuex的核心概念
3.1核心概念包括 State,Mutation,Action,Gentter.Modules
3.2 state部分
State提供唯一的公共资源数据资源,所有共享数据都要统一放到Store的state中进行存储。
组件访问State中数据的第一种方式:
this.$store.state.全局数据名称
第二种方式:
首先从 vuex 中引入 mapState
通过刚才导入的mapState函数,将当前组件所需要的全局数据,映射为当前组件的computed计算属性。便可直接调用使用
注意:虽然可以通过以上两种方式修改 state 内部的数据,但是不建议使用该方式修改。
3.3 Mutation
Mutation用于变更state中的数据,
①:只能使用mutation 变更Store数据,不可以直接操作Store中的数据
②:通过这种方式虽有点繁琐,但是可以集中监控所有数据的变化
话不多说,上图:
第一种方式 触发 mutation (不带参数)
触发 mutation (携带参数)
第二种方式 触发 mutation
3.4 Action
Action 用于处理异步任务,想设置一些定时器等
第一种 触发action (不携带参数)
触发 action (携带参数)
第二种方式 触发 action
3.5Getter
只是对 state中的数据起到包装的作用,并不会修改任何数据。
①Getter可以对Store中已有的数据加工处理之后形成新的数据,类似Vue的计算属性。
②Store中数据发生变化,Getter的数据也会跟着变化。
使用方法:
触发方法
3.6modules
本部分参考自本文为CSDN博主「Meet_you_Q」
原文链接:https://blog.csdn.net/m0_60337445/article/details/122891271
modules 其实就是可以定义多个不同的 store ,互相抽离,防止数据过多,以至于导致单个store 过于臃肿
先简单的举个例子
index.js 文件的内容
import Vue from 'vue'
import Vuex from 'vuex'
import moduleA from '@/store/modules/moduleA'
Vue.use(Vuex)
const store = new Vuex.Store({
state: {
name: 'xxx'
},
mutations: {
changeName(state) {
state.name = 'xxx+++';
}
},
actions: {
},
// 就是使用modules属性在进行注册两个状态管理模块
modules: {
moduleA,
}
});
export default store
moduleA.js的内容
export default {
state: {
name: 'aaa'
},
getters: {},
mutations: {
changeName(state, msg) {
console.log(msg);
state.name = 'aaa+++' + msg;
}
},
actions: {
actChangeName(context, msg) {
console.log(msg);
context.commit('changeName', msg);
}
}
}
调用state中数据的方式
由于我们是使用了模块化的方式,调用最外层的state中的数据 依然是this.$store.state.name
那么在使用modulesA中的方法的时候,是使用 this.$store.state.moduleA.name
调用mutations或者是actions中的方法
由于是没有对模块进行命名空间的,所以默认在使用 this.$store.commit/dispatch() 在提交方法的时候,会对所有状态管理的actions和mutations中的方法进行匹配,这就导致了一个问题,就是当不同模块之间的方法命名一样的情况下,会造成方法同时调用的问题
这个时候,我们需要在定义模块的时候,添加上 namespaced:true 属性
export default {
namespaced: true, // 为当前模块开启独立的 命名空间
state: {
name: 'aaa'
},
getters: {},
mutations: {
changeName(state, msg) {
console.log(msg);
state.name = 'aaa+++' + msg;
}
},
actions: {
actChangeName(context, msg) {
console.log(msg);
context.commit('changeName', msg);
}
}
}
使用命名空间之后的调用方式
我们需要在使用 this.$store.commit/dispatch() 的时候 需要在前面加上我们当前模块名
例如: this.$store.commit("moduleA/changeName");
this.$store.dispatch("moduleA/actChangeName");
这样就可以去调用指定的模块里面的方法,当前最外围的mutations和actions还是一样的调用方式
在使用了模块后属性的参数
mutations和actions的参数是没什么太大变化的
getters中是这样的
getters: {
filters(state, getters, rootState) {
console.log(getters); // 代表的是getters属性
// rootState ---> 根节点的状态(也就是最外层的state)
return state.name + rootState.name;
}
},
使用了模块化之后的辅助函数的使用
<!-- App -->
<template>
<div id="app">
<Panel>
<template #test="{ user }">
{{ user.id }}
</template>
</Panel>
<h2>{{ name }}</h2>
<button @click="changeName">触发mutations</button>
<button @click="actChangeName">触发actions</button>
<h2>{{ filters }}</h2>
</div>
</template>
<script>
// 这里可以导入其他文件(比如:组件,工具js,第三方插件js,json文件,图片文件等等)
// 例如:import 《组件名称》 from '《组件路径》';
import { createNamespacedHelpers } from "vuex";
const { mapState, mapMutations, mapActions, mapGetters } =
createNamespacedHelpers("moduleA"); // 需要指定模块名字
import Panel from "@/components/Panel";
export default {
name: "App",
// import引入的组件需要注入到对象中才能使用
components: {
Panel,
},
data() {
return {};
},
// 监听属性 类似于data概念
computed: {
...mapState(["name"]),
...mapGetters(["filters"]),
},
// 监控data中的数据变化
watch: {},
// 方法集合
methods: {
// handler() {
// this.$store.commit("moduleA/changeName");
// },
...mapMutations(["changeName"]),
// handler2() {
// this.$store.dispatch("moduleA/actChangeName");
// },
...mapActions(["actChangeName"]),
},
beforeCreate() {}, // 生命周期 - 创建之前
// 生命周期 - 创建完成(可以访问当前this实例)
created() {
console.log(this.$store);
},
};
</script>