Vuex学习笔(基于Vue2.x)

  • Vuex学习笔(基于Vue2.x)已关闭评论
  • 142 次浏览
  • A+
所属分类:Web前端
摘要

本人水平有限,如有疏漏或者不正确部分,请大佬指正。 一.Vuex概述 1.1组件之间共享数据的方式

本人水平有限,如有疏漏或者不正确部分,请大佬指正。

一.Vuex概述

1.1组件之间共享数据的方式

父向子传值:v-bind 属性绑定
子向父传值:v-on 事件绑定
兄弟组件之间共享数据:eventBUs
* $on 接收数据的那个组件
* $emit 发送数据的那个组件
特点:适合小范围使用

1.2Vuex是什么

概念:Vuex是实现组建全局状态(数据)管理的一种机制,可以方便的实现组件之间数据的共享

Vuex学习笔(基于Vue2.x) Vuex学习笔(基于Vue2.x)

 

 

 

 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中进行存储。

Vuex学习笔(基于Vue2.x)

 

 

组件访问State中数据的第一种方式

this.$store.state.全局数据名称

 

第二种方式:

首先从 vuex 中引入 mapState

Vuex学习笔(基于Vue2.x)

 

 通过刚才导入的mapState函数,将当前组件所需要的全局数据,映射为当前组件的computed计算属性。便可直接调用使用Vuex学习笔(基于Vue2.x)

 

 

注意:虽然可以通过以上两种方式修改 state 内部的数据,但是不建议使用该方式修改。

 

3.3 Mutation

Mutation用于变更state中的数据,

①:只能使用mutation 变更Store数据,不可以直接操作Store中的数据

②:通过这种方式虽有点繁琐,但是可以集中监控所有数据的变化

 话不多说,上图:

Vuex学习笔(基于Vue2.x)

 

 第一种方式 触发 mutation (不带参数)

Vuex学习笔(基于Vue2.x)

 

 触发 mutation (携带参数)

Vuex学习笔(基于Vue2.x)

 

  第二种方式 触发 mutation 

Vuex学习笔(基于Vue2.x)

 

 3.4 Action 

Action 用于处理异步任务,想设置一些定时器等

第一种 触发action (不携带参数)

Vuex学习笔(基于Vue2.x)

 

 触发 action (携带参数)

Vuex学习笔(基于Vue2.x)

 

 

第二种方式 触发 action

Vuex学习笔(基于Vue2.x)

 

 3.5Getter

只是对 state中的数据起到包装的作用,并不会修改任何数据。

①Getter可以对Store中已有的数据加工处理之后形成新的数据,类似Vue的计算属性。

②Store中数据发生变化,Getter的数据也会跟着变化。

使用方法:

Vuex学习笔(基于Vue2.x)

 

 

触发方法

Vuex学习笔(基于Vue2.x)

 

 

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>