我是靠谱客的博主 秀丽香烟,这篇文章主要介绍后端学习Vue系列之——Vuex,现在分享给大家,希望可以做个参考。

文章目录

    • 前言
    • 正文
      • 1 Vuex的基本使用
      • 2 Vuex的核心概念
        • 2.1 State
        • 2.2 Mutation
        • 2.3 Action
        • 2.4 Getter
        • 2.5 Module
    • 总结
    • 参考

前言

作为一个内心骚动想做点小系统的后端来说,学习Vue是过不去的一个坎,毕竟香嘛~

遂写一篇博文用于记录在Vue中用的比较多的,且不容易记的知识点,方便自己在需要使用时能够查找到相关知识点以及如何快速使用。

在基础篇中,已经介绍了关于Vuex中的一些基础知识点,下面就会陆续介绍Vuex中进阶的一些知识点,总结出来方便自己随时查阅。

正文

在官网上,对于Vuex的介绍为,Vuex是一个专为Vue.js应用程序开发的状态管理模式,说白了就是为了实现组件之间数据的共享。对于Vue来说,组件之间共享数据的方式:

父组件向子组件传值:v-bind属性绑定
子组件向父组件传值:v-on时间绑定
兄弟组件之间共享数据:EventBus
- $on 接受数据的那个组件
- $emit 发送数据的那个组件

一般情况下,只有组件之间共享的数据,才会必要存储到vuex中,对于组件中的私有数据,依旧存储在组件自身的data中即可。

本文是基于黑马《Vuex从入门到实战》视频总结+个人感悟而来

1 Vuex的基本使用

  1. 安装vuex依赖包

npm install vuex --save

  1. 导入vuex包
复制代码
1
2
3
import Vuex from 'vuex' Vue.use(Vuex)
  1. 创建store对象
复制代码
1
2
3
4
5
const store = new Vuex.Store({ // state中存放的就是全局共享的数据 state: {count: 0} })
  1. 将store对象挂载到vue实例中
复制代码
1
2
3
4
5
6
7
8
9
new Vue({ el: '#app', render: h => h(app), router, // 将创建的共享数据对象,挂载到Vue实例中 // 所有的组件,就可以直接从store中获取全局的数据了 store })

2 Vuex的核心概念

Vuex中的主要核心概念如下:

  • State
  • Mutation
  • Action
  • Getter

2.1 State

在Vuex中,State提供唯一的公共数据源,所有共享的数据都要统一放到Store的State中进行存储,这里的Store相当于一个用于存储数据的公共容器。

复制代码
1
2
3
4
5
6
7
const store = new Vue.Store({ state: { count: 0 } ... })

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

复制代码
1
2
this.$store.state.全局数据名称

去过是在html元素组件之间调用,则可以省略this,即:

复制代码
1
2
<span>{{$store.state.全局数据名称}}</span>

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

通过mapState辅助函数方式,实现组件访问State中数据的第二种方式

复制代码
1
2
3
// 1. 从vuex中按需导入mapState函数 import { mapState } from 'vuex'

通过刚才导入的mapState函数,将当前组件需要的全局数据,映射为当前的computed计算属性:

复制代码
1
2
3
4
5
6
// 2. 将全局数据映射为当前组件的计算属性 computed: { // ...表示展开映射,意思就是将全局属性映射为当前组件的计算属性 ...mapState(['count']) }

直接在调用获取组件属性

复制代码
1
2
<span>{{count}}</span>

2.2 Mutation

Vuex中的Mutation是用于变更Store中的数据。

在Vuex中,只能通过mutation变更Store数据,不可以直接操作Store中的数据。虽然通过mutation的方式来操作数据,虽然繁琐了一点,但是却可以集中监控所有数据的变化。

例如需要让全局数据自增加1,则可以通过如下的方式在Mutation中定义

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
const store = new Vuex.Store({ state: { count: 0 }, mutations: { add(state) { //变更状态 state.count++; } } })

定义完mutation之后,下面就来介绍下Vuex的触发方式

触发mutation方式一

通过$store.commit()函数来触发mutation。

复制代码
1
2
3
4
5
6
7
methods: { handle1 () { // 触发mutations的第一种方式 this.$store.commit('add') } }

接着就可以通过@click方法来调用handle1,从而来触发mutation函数。

另外,可以在触发mutation函数时,传入参数

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const store = new Vuex.Store({ state: { count: 0 }, mutations: { add(state) { //变更状态 state.count++; }, addN(state, n) { state.count += n; } } })

然后定义handler2

复制代码
1
2
3
4
5
6
methods: { handler2: { this.$store.commit('addN', 5); } }

触发mutation方式二

通过导入mapMutations辅助函数来触发mutations。

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 1. 从vuex中按需导入mapMutations函数 import { mapMutations } from 'vuex' ... // 2. 将制定的mutations函数映射为当前组件的methods函数 methods: { // 将add和addN方法映射为methods中的函数,拱当前组件使用。 ...mapMutations({'add', 'addN'}), handleAdd() { this.add(); }, handleAddN(n) { this.addN(n); } // 或者直接在标签元素中直接@click=add() }

对于mutations来说,只能够实现同步操作,不可以执行异步操作的。

2.3 Action

从vuex官网中可以了解到,Action类似于mutation,不同之处在于:

  • Action 提交的是 mutation,而不是直接变更状态。
  • Action 可以包含任意异步操作。

可以得出一个结论就是,如果通过异步操作变更数据,必须通过Action,而不能使用Mutation,但是在Action中还是要通过触发Mutation的方式间接变更数据。

如何定义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
28
29
const store = new Vuex.Store({ state: { count: 0 }, mutations: { add(state) { //变更状态 state.count++; }, addN(state, n) { state.count += n; } }, actions: { // 通过context去调用mutation addAsync(context) { setTimeout(() => { context.commit('add' }, 1000) }, // 调用Actions是也可以传入参数 addNAsync(context, n) { setTimeout(() => { context.commit('addN', n); }, 1000); } } })

需要再次强调的是,只有通过mutation中定义的函数,才有权利去修改state中的数据,因此actions最终还是要调用mutation。

触发Actions的第一种方式

复制代码
1
2
3
4
5
6
7
8
9
methods: { handleAddAsync() { this.$store.dispatch('addAsync'); }, handleAddNAsync() { this.$store.dispatch('addNAsync', n); } }

触发Actions的第二种方式

可以通过mapActions辅助函数的方式来触发Actions。

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 1. 从vuex中按需导入mapActions函数 import { mapActions } from 'vuex' ... // 2. 将指定的actions函数,映射为当前组件的methos函数 methods: { ...mapActions(['addAsync', 'addNAsync'), handleAddAsync() { this.addAsync(); }, handleAddNAsync(n) { this.addNAsync(n); } }

2.4 Getter

在Vuex官网中,用到了派生这一词来介绍Getter,在这里可以理解为就是用于对Store中的数据进行加工处理,形成新的数据,类似Vue的计算属性。Getter的数据是基于Store中的数据的,所以当Store中数据发生变化时,Getter中的数据也会随之变化。

定义Getter

例如state中存有todos计划项,其对象有一个done状态表示完成与否。

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
const store = new Vuex.Store({ state: { todos: [ { id: 1, text: '...', done: true }, { id: 2, text: '...', done: false } ] }, getters: { // 这里通过getters定义的doneTodos方法来过滤已完成的todo项 doneTodos: state => { return state.todos.filter(todo => todo.done); }, // 这里还可以通过传入getters对象来获取其他方法 doneTodosCount: (state, getters) => { return getters.doneTools.length; }, // 传入参数 getTodoById: (state) => (id) => { return state.todos.find(todo => todo.id == id); } } })

触发Getter定义函数的第一种方法

复制代码
1
2
3
this.$store.getters.doneTodos // -> [{id: 1, text: '...', done: true}] this.$store.getters.doneTodosCount // -> 1

触发Getter定义函数的第二种方法

通过mapGetters来触发Getter中定义的函数

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 1. 导入mapGetters辅助函数 import { mapGetters } from 'vuex' ... // 2. 将制定的Getters函数映射为当前组件的函数 methods: { ...mapGetters(['doneTodos', 'doneTodosCount']), handleDoneTodos() { this.doneTodos(); } }

2.5 Module

当Store中存放了非常多非常大的共享数据对象时,应用会变的非常的复杂,Store对象也会非常臃肿,所以Vuex提供了一个Module模块来分隔Store。通过对Vuex中的Store分隔,分隔成一个一个的Module模块,每个Module模块都拥有自己的state、mutation、actions和getters。

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
const moduleA = { state: () => ({ ... }), mutations: { ... }, actions: { ... }, getters: { ... } } const moduleB = { state: () => ({ ... }), mutations: { ... }, actions: { ... } } const store = new Vuex.Store({ modules: { a: moduleA, b: moduleB } }) store.state.a // -> moduleA 的状态 store.state.b // -> moduleB 的状态

对于模块中的mutations和getters,传入的第一个参数规定为state,而actions则依旧是context参数。如下:

复制代码
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 moduleA = { state: { count: 0 }, mutations: { increment (state) { // 这里的 `state` 对象是模块的局部状态 state.count++ } }, getters: { doubleCount (state) { return state.count * 2 } }, actions: { // context对象其实包含了 state、commit、rootState。 incrementIfOddRootsum (context) { if ((context.state.count + context.rootState.count) % 2 === 1) { // 调用mutations commit('increment') } } } }

在module中通过mapState、mapGetters、mapActions和mapMutations等辅助函数来绑定要触发的函数

第一种方式

复制代码
1
2
3
4
5
6
7
methods: { ...mapActions([ 'some/nested/module/foo', 'some/nested/module/bar' ]) }

在vuex中,可以为导入的state、getters、actions以及mutations命名别名,,这样可以方便调用

复制代码
1
2
3
4
5
6
7
methods: { ...mapActions([ 'foo': 'some/nested/module/foo', 'bar': 'some/nested/module/bar' ]) }

第二种方式
对于这种情况,你可以将模块的空间名称字符串作为第一个参数传递给上述函数,这样所有绑定都会自动将该模块作为上下文。于是上面的例子可以简化为:

复制代码
1
2
3
4
5
6
7
methods: { ...mapActions('some/nested/module', [ 'foo', // -> this.foo() 'bar' // -> this.bar() ]) }

第三种方式
可以通过使用 createNamespacedHelpers 创建基于某个命名空间辅助函数。它返回一个对象,对象里有新的绑定在给定命名空间值上的组件绑定辅助函数:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
import { createNamespacedHelpers } from 'vuex' const { mapState, mapActions } = createNamespacedHelpers('some/nested/module') export default { methods: { // 在 `some/nested/module` 中查找 ...mapActions([ 'foo', 'bar' ]) } }

总结

通过视频学习到Vuex基础知识后,再去Vuex的官方文档,阅读起来也不会那么的吃力了。

本文以自己能理解的方式详细介绍了Vuex的概念以及核心知识点,下面再总结一下:

  1. Vuex主要用于管理Vue组件中共享的数据。
  2. Vuex中有state、mutation、action、getter等核心概念。
  3. 获取state可以通过this.$store.state.xx或者是通过定义mapState来获取。
  4. 修改state中的变量需要通过mutation函数实现,而mutation的触发由两种方式,一种是通过this.$store.commit()函数,另外一种就是通过mapMutations来实现。
  5. mutation只能用于修改数据,而Actions可以实现异步操作。
  6. 通过Actions的异步操作+mutation的修改数据,可以实现异步修改数据。调用Actions有两种方式,第一种是通过this.$store.dispatch来调用,另外一种方式是通过mapActions来调用。
  7. Getters函数用于对Store中数据进行加工,不会修改原本Store中的数据;Getters中的数据会受Store中数据进行影响。

参考

  • 《Vuex从入门到实战》
  • Vuex官网

最后

以上就是秀丽香烟最近收集整理的关于后端学习Vue系列之——Vuex的全部内容,更多相关后端学习Vue系列之——Vuex内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(82)

评论列表共有 0 条评论

立即
投稿
返回
顶部