目录
本文对 Vuex 整个创建即使用,都有详细的步骤介绍,如果你是 Vuex 的初学者或者遗忘当做资料回顾,相信都能对你起到一定的作用
Vuex 简介与执行流程概述
-
Vuex:
是在 Vue 中实现集中式状态(数据)管理的一个 Vue 插件
,对 Vue 应用中多个组件的共享状态及逆行集中式的管理(读/写),也是一种组件间通信的方法,且适用于任意组件间通信 -
Vuex中共有五个状态 State Getter Mutation Action Module ,下面来简单介绍一下它们
-
State
:提供唯一的公共数据源,所有共享的数据统一放到 store 下的 state 存储 -
Mutation
:用于更改 state 中存储的数据 -
Action
:用来处理一些异步操作,或者处理当前方法需要进行一些复杂的业务 -
Getter
:对 state 中的数据进行加工 -
Module
:将 store 进行模块化处理
-
-
图解:
-
执行流程如下:
-
那看了上述的图解又为什么需要 Actions 这个转交呢?假设我们现在在进行
后端API
的接口请求,我们并不知道需要传递什么值,只是发送了一个方法,dispatch('getInfo')
,此时 Actions 中就会触发同名方法getInfo
,在 Actions 中我们就可以进行 API 的请求,并将获取的数据通过 commit 方法,发送给 mutations 中,让其去更新 state 中的值 -
当然如果你更改的值是确定的,也可以直接在组件中使用 commit 去让 mutations 更新 state 中的数据
Vuex 的环境搭建
如果采用脚手架方式进行创建时勾选了Vuex,可以忽略此步骤
-
引入 Vuex:
Vue2 安装 3 版本,Vue3 安装 4 版本
npm install vuex@3
-
在 src 目录下创建
store
文件夹 -
在 store 文件下创建
index.js
文件 -
在 index.js 文件下进行如下配置:
// 引入 Vue import Vue from 'vue' // 引入Vuex import Vuex from 'vuex' // 使用Vuex插件 Vue.use(Vuex) // actions——用于响应组件中的传递的方法 const actions = {} // mutations——用于操作数据 state 中的数据 const mutations = {} // state——用于存储数据 const state = {} // 通过 Vuex 中的 Store 方法创建并暴露store // 同时传入配置项 export default new Vuex.Store({ actions, mutations, state })
-
Tips:
这里我们先配置 actions mutations state,后续的 getter 与 module 在后续会进行讲解
-
将配置好的 Vuex 在 main.js 文件下引入
//引入Vue import Vue from 'vue' //引入App import App from './App.vue' //引入store import store from './store' //关闭Vue的生产提示 Vue.config.productionTip = false //创建vm new Vue({ el: '#app', render: h => h(App), // kv 一致省略 v store })
Vuex 的基本使用
-
首先我们创建一个组件,本示例组件名为 Teacher,先搭建一下Teacher组件的基本结构,Teacher组件内容如下:
<template> <div> <h1>Vuex的基本使用--Teacher</h1> <input type="text" placeholder="输入添加老师的名称" v-model="teacher.name" /> <br /> <input type="text" placeholder="输入添加老师的年龄" v-model="teacher.age" /> <br /> <button @click="addTeacher">添加老师</button> <button @click="removeTeacher">删除年龄年龄大于50的教师</button> <h3>教师列表</h3> <ul> <li>姓名:xxx,年龄:???</li> </ul> </div> </template> <script> // 引入生成唯一id插件 import { nanoid } from 'nanoid' export default { name: 'Teacher', data() { return { teacher: { name: '', age: null } } }, methods: { // 添加 addTeacher() {}, // 删除 removeTeacher() {} } } </script> <style scoped> button { margin: 10px; } </style>
-
然后将 Teacher 组件在 App 组件中使用,这步比较简单,就不在进行赘述了
-
我们先看一下
添加方法
按照完整的流程实现步骤:-
Teacher 组件中 addTeacher 方法如下:
addTeacher() { // 获取需要添加教师的姓名和年龄 // 利用 nanoid 生成唯一 id const teacherObj = { id: nanoid(), name: this.teacher.name, age: this.teacher.age } // 将获取的教室信息通过 dispatch 方法提交给 store 中的 actions 进行处理 // dispatch() 方法 // 参数一:方法名,自己随意配置,符合规范即可 // 参数二:传递值 this.$store.dispatch('addTeacher', teacherObj) },
-
在 store 的 index.js 文件下的 actions 下定义方法:
const actions = { // 添加教师 // 这里的定义的方法接收两个参数 // 参数一:context 上下文 // 参数二:接收组件中使用 dispatch 传递的值 addTeacher: function (context, value) { // 这里我们需要利用上下文中的 commit 提交到 mutations 中 // 我们一般约定:commit 的方法名为大写 // commit 方法: // 参数一:方法名 // 参数二:传递值 context.commit('ADD_TEACHER', value) }, }
-
上述的 addTeacher 可能看起来有一些繁杂,我们可以简写一下,两种写法都可以,按照个人习惯即可
// 同样我们可以将 addTeacher 方法进行简写一些 // 我们这里只需要使用 context 的 commit 方法,可以使用解构单独提取 addTeacher({commit}, value){ commit('ADD_TEACHER', value) },
-
在 mutations 定义方法:
const mutations = { // 通过 commit 提交会自动触发 mutatios 中同名的方法 // mutatios 中的方法接收两个参数 // 参数一:当前实例的 state // 参数二:commit 方法传递的值 ADD_TEACHER(state, value) { // 将新教师的信息更新到 state 仓库中 state.teacherList.unshift(value) }, }
-
state 中内容如下:state 中的数据会直接解析并引用到相关的组件中
const state = { // 教师列表 teacherList: [] }
-
因为开始渲染,我们需要将原来 Teacher 组件中的
ul列表
的固定模板改为循环渲染
:<ul> <!-- 模板中使用可以省略 this --> <li v-for="t in $store.state.teacherList" :key="t.id"> 姓名:{{ t.name }},年龄:{{ t.age }} </li> </ul>
-
实际的运行效果大家可以可以按照步骤放入 vue 项目中运行一下
-
-
看了上述的添加方法实现,大家可能会疑惑了,为什么 mutations 中就可以完成的事情,需要经过 actions 这一步的转接呢?具体的原因我们放在后续讲解,这里可以告诉大家,如果我们需要修改的数据不需要做过多的处理,如上述示例中单纯的增删改查,且增删改查的值我们本身就拥有们就可以直接在
组件中通过 commit 方法和 mutations 对话
,去更新 state 中的值,如下:addTeacher() { const teacherObj = { id: nanoid(), name: this.teacher.name, age: this.teacher.age } // 注意这里的方法名需要修改为 mutations 中的方法名 this.$store.commit('ADD_TEACHER', teacherObj) }
-
那通过删除年龄大于50岁这个方法来给大家演示一下 actions 的作用,上述重复过如 dispatch 和 commit 等方法的说明后续就不再进行注解了,下面来看一下具体的实现步骤:
-
在本次方法的演示中我已经提前通过 addTeacher 添加方法添加了一些教师数据,如图:
-
Teacher 组件中 removeTeacher方法如下:
// 删除 removeTeacher() { // 通过 this.$store.state.teacherList 就可以获取 state 中的 teacherList const teacherList = this.$store.state.teacherList // 发送删除方法 this.$store.dispatch('removeTeacher', teacherList) }
-
在 actions 下定义方法:
const actions = { removeTeacher({ commit }, value) { // 筛选其中年龄大于 50 的教师 const result = value.filter(item => item.age < 50) // 若是对 filter 方法不熟悉,大家可以自己百度在回顾一下 commit('REMOVE_TEACHER', result) } }
-
在 mutations 下定义方法:
const mutations = { REMOVE_TEACHER(state, value) { state.teacherList = value }, }
-
结果如图:
-
通过删除教师这个案例,相信大家可以看出 actions 的一些作用,通过 actions 可以处理一些代码的业务逻辑,最重要的是在此处进行一些后端接口的请求,将请求的数据带给 mutations,大致方式差不多,这里就给大家写一段示例代码进行演示,如下:
const acions = { // 假设当前接口获取的书籍信息 // 因为是在 actions 中发送数据请求。就不需要携带值 getBookInfo({commit}){ // 关于 axios 本示例就不进行讲解了 axios.get('https://xxx/v1/books').then( res =>{ commit('GET_BOOK_INFO', res) }) } }
-
context 上下文
-
这里我们对 actions 中的 context 进行一些详细的解析
-
首先我们可以先看一下 context 的打印结果
-
通过上述打印结果我们可以看到具备不少的方法,通过这些方法可以将 context 理解为一个简化版的 store,这里我重点给大家讲解一下 commit dispatch state
-
commit
:之前的示例中也给大家说明过,可以传递两个参数- 参数一:传递给 mutations 中的方法名,一般我们约定为大写,当然可以自己自定义,符合命名规范即可
- 参数二:需要传递的值
- 当 commit 执行后,mutations 中 和 commit 中
参数一
的同名方法会自动调用
-
state
:获取 state 仓库中的数据,拿到这个数据的作用我们与 dispatch 一起进行讲解 -
dispatch
:大家可能不理解为什么这里需要 dispatch,在 actions 中可能会出现一个方法中内部业务复杂,代码过多情况下,就会显得这个方法十分的臃肿,不利于维护和阅读,我们知道 dispatch 可以触发 actions ,那么我们就可以通过再次 dispatch 进行方法中业务分离,抽取一部分代码放入其他方法执行,我们来看一下示例:const acions = { // 此处的仅作用于演示,因此方法名设计的比较随意 demo1(context){ // 这里用一句输出代替实际执行的业务 console.log('处理的第一部分逻辑') // 假设最后得到的结果使用 result 变量接收,并需要对这个结果做进一步的处理 // 我们就可以使用 dispatch 触发另外一个方法进行处理 context.dispatch('demo2', result) }, demo2(context, value) { console.log('对数据value进行了处理') // 此时我们业务完成,可以进行提交 context.commit('DEMO_2', value) // 如果我们还需要进一步的分离,可以再次进行 dispatch } }
-
相信现在大家对于 context 已经了有了一些大概的了解了,下面我们在介绍一下 Getter
Getter 的使用
-
现在我们需要给最开始 index.js 文件在添加一项配置
import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) const actions = { removeTeacher({ commit }, value) { const result = value.filter(item => item.age < 50) commit('REMOVE_TEACHER', result) }, addTeacher({ commit }, value) { commit('ADD_TEACHER', value) } } const mutations = { REMOVE_TEACHER(state, value) { state.teacherList = value }, ADD_TEACHER(state, value) { state.teacherList.unshift(value) } } // 添加 getters // getters 的方法可以接收一个参数 state // 依靠返回值决定值,与计算属性类似,计算属性不了解的可以自己查阅一下资料 const getters = {} const state = { teacherList: [] } export default new Vuex.Store({ actions, mutations, state, getters })
-
那我们现在先来使用一下 getters ,getters 在最开始我们就提到过,主要是对 state 中的数据进行加过,示例如下:
const getters = { // 所有年龄小于50岁的教室名称后面都标记 * addSing(state) { const newArr = [] state.teacherList.forEach(item => { if (item.age < 50) { const obj = { id: item.id, name: item.name + '*', age: item.age } newArr.push(obj) } else { newArr.push(item) } }) // 此处为了展示不一样的效果,选择返回一个新的数组,避免修改原数组 return newArr } }
-
那如何获取 getters 中的数据呢,我们在 Teacher 组件中演示一下获取的方式
mounted() { console.log(this.$store.getters.addSing) },
-
如果实在模板中省略 this 即可,我们使用 getters 加工后的数据渲染展示一下,结构如下:
<h3>教师列表--state</h3> <ul> <li v-for="t in $store.state.teacherList" :key="t.id"> 姓名:{{ t.name }},年龄:{{ t.age }} </li> </ul> <h3>教师列表--getters</h3> <ul> <li v-for="a in $store.getters.addSing" :key="a.id"> 姓名:{{ a.name }},年龄:{{ a.age }} </li> </ul>
-
渲染如图:
-
以上就是 getter 的基本使用,大家理解为 state 的加工厂就好了
mapState 详解
-
我们上述的示例中已经实现了整个 Vuex 的基本使用,但是不知道大家有没有发现一段代码总是在重复,
$store.state.xxx
,特别是在模板中,看起来就比较臃肿,或许也可以说放进计算属性中,就可以改变模板中的代码,但是这样计算属性在获取的时候,this.$store.state.xxx
是不是也是重复了呢,这时候就是我们要说的关键所在了,mapState
,它可以帮助我们省去这些重复的代码 -
首先我们先给教室列表一些初始数据,方便我们获取看到结果
const state = { teacherList: [ { id: '001', name: '田七', age: 25 }, { id: '002', name: '赵六', age: 22 }, { id: '003', name: '王五', age: 56 }, { id: '004', name: '李四', age: 33 }, { id: '005', name: '张三', age: 60 } ] }
-
首先我们需要在
Teacher
组件中 Vuex 中引入mapState
,如果大家对于这种引入方式存在疑惑的话,可以去回顾一下模块化的知识// 引入 Vuex 中的 mapState import { mapState } from 'vuex'
-
引入之后我们先来看一下 mapState
mounted() { // mapState要求我们传入一个配置对象 // 配置对象中的 k 表示我们在组件中使用这个数据的变量名 // 配置对象中的 v 表示在 state 中查找的数据名称 // - 我们知道,这个 k 值其实是一个字符串,只是平常简写了,在执行的时候还是会自动包裹一个字符串,所以 v 值不仅要使用 state 中的名称,还需要包裹一个字符串 // - 如果不包裹字符串就表示当前页面的一个变量 const res = mapState({ tList: 'teacherList' }) console.log(res) },
-
通过上述代码可以得到如下输出,如图:
-
最外层可以看到,是一个对象,内部是一个函数,函数名叫 tList
-
下面我们来使用一下 mapState,刚刚我们提到,可以使用计算属性让模板中的代码进行精简,那我们在计算属性中使用一下 mapState,示例如下:
computed: { // 在这里使用 ... 是展开运算符的语法,我们刚才打印的时候可以发现是一个对象里面包裹函数 // 所以使用 ... 展开 mapState,如果没有理解的朋友可以记住这种写法,或者回顾一些 es6 的展开运算符 // - 展开之后 tList 就是一个函数,且这个函数的返回值就是 state 中获取的值,所以无法使用 kv 一致省略 v,因为这种简写形式,后续的 v 会被当成是一个变量解析 ...mapState({ tList: 'teacherList' }) },
-
我们在得到这个值之后有什么作用呢?模板中我们就可以省略 $store.state.xxx,一长串的引用,直接使用 tList 替代即可,示例如下:
<h3>教师列表--state</h3> <ul> <li v-for="t in tList" :key="t.id"> 姓名:{{ t.name }},年龄:{{ t.age }} </li> </ul>
-
可以看到是不是精简了很多,同样在 js 中也可以直接使用
this.tList
即可获取,是不是也简洁了许多,哪还能不能在简单一些呢,答案当然可以,上述展示的只是对象写法,简写可不是 kv 一直省略 v,为什么不是可以在看看上述的注解,而是数组写法,示例如下:computed: { // 数组写法 // 这种写法的意思是:在计算属性中,属性名叫 teacherList,且在 state 中寻找的数据也叫 teacherList ...mapState(['teacherList']) },
-
运行结果如图:
-
使用数组写法,模板中的 tList 名称也需要换成 teacherList,这一步就不在进行代码演示了,大家自行修改即可,经过对象写法和数组写法按照个人习惯即可,不过还是更推荐大家使用数组写法,毕竟可以从一定程度上避免重新取名的烦恼,如果对象写法取同名是不是还是数组写法更好呢
-
可能写到这有些小伙伴会有一些疑惑,这个可以在 methods 中使用吗,也是可以的,也是使用扩展运算符展开即可,但是这样获取的数据在模板中无法使用,所以就没有太大的必要了,还是一样给大家写一段示例,示例如下:
methods: { ...mapState(['teacherList']) }
mapGetters 详解
-
经过 mapState 的使用之后,相信大家对于怎么使用 mapGetters 想必也不是什么难事,那我就不在进行赘述了,直接使用代码给大家演示一下
-
在组件中,引入 mapGetters
import { mapState, mapGetters } from 'vuex'
-
在计算属性中使用 mapGetters
computed: { // 同理,使用数组写法引入,对象写法请大家参考 mapState 的对象写法 ...mapGetters(['addSing']) },
-
同步修改模板中的数据渲染
<h3>教师列表--getters</h3> <ul> <li v-for="t in addSing" :key="t.id"> 姓名:{{ t.name }},年龄:{{ t.age }} </li> </ul>
-
运行结果如图:
mapMutations 详解
-
既然存在 mapState 与 mapGetters,那肯定也具备 mapActions 与 mapMutations,我们先讲解 mapMutations,mapActions 后续在讲解
-
为了方便演示,我们重新定义一个方法,点击按钮 state 中的 num 就 + 1,在 html 结构添加一个展示框和按钮,如下:
<h2>state的num为:xxx</h2> <button @click="addOne">点击num自增1</button>
-
页面样式如图:
-
在 state 中初始化 num: 0,就不在演示了
-
引入 mapMutations
import { mapState, mapGetters, mapMutations } from 'vuex'
-
因为自增 + 1的方法属于简单的自增,我们可以直接与 mutations 对话,在方法中使用 mapMutations ,示例如下:
methods:{ // addOne 为当前组价中触发的事件回调名称,ADD_ONE 为在 mutations 中的名称方法 // 同时我们发现 addOne 并没有传送自增的值过去,那应该怎么传呢,可以在定义事件的时候传递一个参数 // 他会自动帮我们触发 commit 方法与 mutations 对话 ...mapMutations({ addOne: 'ADD_ONE' }) }
-
在模板中定义事件的时候传递一个参数,修改如下:
<button @click="addOne(1)">点击num自增1</button>
-
记得在 mutations 中定义方法,
ADD_ONE
,示例如下:const mutations = { // 自增 + 1 ADD_ONE(state, value) { state.num += value } }
-
即可实现自增 + 1的需求,那么是不是只能在定义事件的时候传递参数呢?也不尽然,还可以使用事件触发方法的写法,我们一起看一下,html 中将参数取消,修改如下:
<button @click="addOne">点击num自增1</button>
-
addOne 方法如下:
methods:{ // 点击触发 addOne 方法时,我们在调用一下另外的方法,并传递值 addOne() { this.jiaOne(1) } }
-
可能大家也猜到了,jiaOne 就是在 mapMutations 中触发的方法,修改如下:
methods:{ // 点击触发 addOne 方法时,我们在调用一下另外的方法,并传递值 addOne() { this.jiaOne(1) }, ...mapMutations({ jiaOne: 'ADD_ONE' }) }
-
后者这种写法比较繁杂一些,具体使用那种写法,根据需求和个人习惯而定,既然存在对象写法,那一定也会有数组写法,就是名称都一致即可,示例如下:
methods:{ // 记得事件名也需要同步修改成 ADD_ONE,数组写法大家脑海中编写一次就可以发现,不是很好用,所以不推荐 // 大家理解和知道即可 ...mapMutations(['ADD_ONE']) }
mapActions 详解
-
mapActions 与 mapMutations 就像一对兄弟,使用的方法和 mapMutations 一样,所以我们直接进行演示
-
我们演示就采用开始定义的删除年龄大于 50 的方法,如果有一点遗忘的小伙伴,可自行回看一下,首先我们需要定义事件的时候传递一个参数,所以 html 结构中也需要修改一下,示例如下:
<!-- 此处传递的参数 teacherList 来自于 mapState --> <button @click="removeTeacher(teacherList)">删除年龄年龄大于50的教师</button>
-
在 methods 中使用 mapActions
methods:{ // 同理,会自动帮我们触发 dispatch 方法与 actions 对话 ...mapActions({ removeTeacher: 'removeTeacher' }) }
-
执行结果如图:
-
可以看到结果运行和之前别无二致,
利用两个函数调用传递参数
和数组写法
就不在进行展示了,大家有兴趣可以自行练习一下
module 详解
-
经历这么久的叙述,我们终于进入到了最后一关
模块化
,也是至关重要的一关,项目越大越是必不可少,下面就让我们一起来使用一下 -
新增了 module ,那么是不是意味着配置 Vuex 的index.js 文件是不是也需要对应的变化,如下:
import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) // 定义 Teacher 组件的配置 // 将 actions mutations mutations state 放入配置项 const teacherOptions = { actions: { removeTeacher({ commit }, value) { const result = value.filter(item => item.age < 50) commit('REMOVE_TEACHER', result) }, addTeacher({ commit }, value) { commit('ADD_TEACHER', value) } }, mutations: { ADD_ONE(state, value) { state.num += value }, REMOVE_TEACHER(state, value) { state.teacherList = value }, ADD_TEACHER(state, value) { state.teacherList.unshift(value) } }, getters: { addSing(state) { const newArr = [] state.teacherList.forEach(item => { if (item.age < 50) { const obj = { id: item.id, name: item.name + '*', age: item.age } newArr.push(obj) } else { newArr.push(item) } }) return newArr } }, state: { teacherList: [ { id: '001', name: '田七', age: 25 }, { id: '002', name: '赵六', age: 22 }, { id: '003', name: '王五', age: 56 }, { id: '004', name: '李四', age: 33 }, { id: '005', name: '张三', age: 60 } ], num: 0 } } export default new Vuex.Store({ // 使用 modules 开模块化 modules: { // 传入配置项 teacherOptions,kv 一致省略 v teacherOptions } })
-
修改完成之后我们现在通过 this.$store.state来 看一下是什么,如图:
-
是不是只有我们刚刚配置的 teacherOptions 配置对象了,那我们现在在组件中应该如何使用呢?示例如下:
computed: { // 我们通过打印 state,发现是不是只有 teacherOptions ,那么我们此处就需要修改一下引用 // ...mapState(['teacherList', 'num']), // 直接引入配置对象 teacherOptions ...mapState(['teacherOptions']) },
-
修改了引用,那模板中引用也需要修改一下,如下:
<h3>教师列表--state</h3> <ul> <li v-for="t in teacherOptions.teacherList" :key="t.id"> 姓名:{{ t.name }},年龄:{{ t.age }} </li> </ul>
-
运行结果如图:
-
那这样是不是觉得使用总需要使用 teacherOptions 作为前缀进行使用比较麻烦,有没有办法和之前一样直接使用呢,也是可以的,但是有个前提,需要开启命名空间,示例如下:
const teacherOptions = { // 在配置对象的时候,开启这个命名空间 namespaced: true, actions: { removeTeacher({ commit }, value) { const result = value.filter(item => item.age < 50) commit('REMOVE_TEACHER', result) }, addTeacher({ commit }, value) { commit('ADD_TEACHER', value) } }, mutations: { ADD_ONE(state, value) { state.num += value }, REMOVE_TEACHER(state, value) { state.teacherList = value }, ADD_TEACHER(state, value) { state.teacherList.unshift(value) } }, getters: { addSing(state) { const newArr = [] state.teacherList.forEach(item => { if (item.age < 50) { const obj = { id: item.id, name: item.name + '*', age: item.age } newArr.push(obj) } else { newArr.push(item) } }) return newArr } }, state: { teacherList: [ { id: '001', name: '田七', age: 25 }, { id: '002', name: '赵六', age: 22 }, { id: '003', name: '王五', age: 56 }, { id: '004', name: '李四', age: 33 }, { id: '005', name: '张三', age: 60 } ], num: 0 } }
-
开启命名空间之后呢?我们对 mapState 进行修改,修改如下:
computed: { // ...mapState(['teacherOptions']) // 我们还需要传入一个参数 // 参数一:配置项名称 // 参数二:引入配置项中的数据 ...mapState('teacherOptions', ['teacherList']) },
-
在模板中使用,将引用去掉即可,如下:
<h3>教师列表--state</h3> <ul> <li v-for="t in teacherList" :key="t.id"> 姓名:{{ t.name }},年龄:{{ t.age }} </li> </ul>
-
运行结果大家可以自己测试一下,这里就不在进行展示了,mapGetter 的写法也是一样的,示例如下:
computed: { ...mapGetters('teacherOptions', ['addSing']) },
-
运行结如图:
-
mapActions 写法也一样
methods:{ ...mapActions('teacherOptions', { removeTeacher: 'removeTeacher' }), }
-
mapMutations 我就不在进行演示了
-
我们还可以在 store 文件夹新建一个 teacher.js 文件,然后引入进 index.js 文件,可以实现更好的代码分离,teacher.js 文件内容如下:
// 默认导出 export default { namespaced: true, actions: { removeTeacher({ commit }, value) { const result = value.filter(item => item.age < 50) commit('REMOVE_TEACHER', result) }, addTeacher({ commit }, value) { commit('ADD_TEACHER', value) } }, mutations: { ADD_ONE(state, value) { state.num += value }, REMOVE_TEACHER(state, value) { state.teacherList = value }, ADD_TEACHER(state, value) { state.teacherList.unshift(value) } }, getters: { addSing(state) { const newArr = [] state.teacherList.forEach(item => { if (item.age < 50) { const obj = { id: item.id, name: item.name + '*', age: item.age } newArr.push(obj) } else { newArr.push(item) } }) return newArr } }, state: { teacherList: [ { id: '001', name: '田七', age: 25 }, { id: '002', name: '赵六', age: 22 }, { id: '003', name: '王五', age: 56 }, { id: '004', name: '李四', age: 33 }, { id: '005', name: '张三', age: 60 } ], num: 0 } }
-
index.js 文件如下:
import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) // 引入 teacher 配置项 import teacherOptions from './teacher' export default new Vuex.Store({ // 使用 modules 开模块化 modules: { // kv 一致省略 v teacherOptions } })
-
是不是看起来就更加简洁美观,且利于后续的维护呢,如果还有其他组件按照 Teacher 组件的方式在继续添加即可
多组件数据共享
-
新建一个组件 Student,组件需要使用 Tacher 组件的教室列表,下面我就不在分步进行演示了,直接展示 Student 组件的内容,示例如下:
<template> <div> <h1>Vuex的模块化--Student</h1> <h3>使用 Tacher 组件的教师列表</h3> <ul> <li v-for="t in teacherList" :key="t.id"> 姓名:{{ t.name }},年龄:{{ t.age }} </li> </ul> </div> </template> <script> import { mapState } from 'vuex' export default { name: 'Student', computed: { ...mapState('teacherOptions', ['teacherList']) } } </script> <style></style>
-
将组件注册使用我就不在赘述了,直接大家看结果吧,如图:
总结
关于 Vuex 的全部使用就已经全部介绍完毕了,最后来谈一下什么时候使用 Vuex 吧,如果你的项目并不打算开发中大型的单页面应用,那 Vuex 对你来说可能是比较繁琐的,如果你需要开发中大型项目,那么我相信 Vuex 一定是你的不二选择,感谢观看