Vue从甜小白到皮大佬系列(八) Vuex

阅读时间预计8分钟,读完本文你将收获以下知识点,记得点赞👍哦~ html

1、啥是Vuex?

Vuex是用来管理Vue的全部组件状态,说白了就是组件中通讯的一种高级方式。前端

Vuex官方文档已经讲解的很是详细,建议通读一遍,本文是本身的学习总结实践和概括,有些概念和语句借鉴官方。vue

2、为何使用Vuex?

在以前的文章组件通讯中咱们讲了组件中的经常使用通讯方式有props,$emit/v-on,$parent / $children & $refs这三种,他们的局限性在于只能在父子组件中通讯,不能在兄弟组件中通讯,另外两种是Bus中央总线发布订阅模式能够在任意组件之间进行通讯,可是若是在大型项目中不免会有些许瓶颈,组件之间的耦合度较高,那么这时Vuex就恰到好处的出现了,他可以合理的管理各组件中的状态(通讯,方法捕获实现,数据传递),将状态从组建中剥离开来,定义和隔离状态管理中的各类概念并经过强制规则维持视图和状态间的独立性,这样咱们的代码将会变得更结构化且易维护。vuex

3、Vuex核心

Vuex提供一个单例Store它就至关于一个容器同样,包含着你应用中的state公共数据,咱们经过单例Store来统一的按照既定规则来动态的管理这些state,这就是Vuex的核心。api

1.State

state就是一个纯对象,上面有一些状态挂载,并且一个应用应该只有一个statestore.js缓存

export default new Vuex.Store({
 state : {//初始状态
    name:'极客James', 
    height:180,
    age:27
  } 
})
复制代码

1.1mapState:

使用 mapState 辅助函数帮助咱们生成计算属性,在须要通讯的组件中经过import {mapState} from 'vuex'引入辅助函数,而后要在计算属性computed钩子里面进行数据的映射。bash

mapState辅助函数使用的三种方式:

  • 第一种:计算属性经过箭头函数取返回值
computed:mapStates({
    name:state=>state.name,
    height:state=>state.name,
    age:state=>state.age
})
复制代码
  • 第二种方法:利用ES6的...延展特性 (推荐作法)
computed:{
    ...mapState([
        'name',
        'height',
        'age'
    ])
}
复制代码
  • 第三种方法:利用ES6的...延展特性经过对象取值
computed:{
    ...mapState({
        name:state=>state.name,
        height:state=>state.height,
        age:state=>state.age
    })
}
复制代码

在组件中取数据app

<template>
  <div class="app">
    <div>我是store里面的数据姓名:{{name}}</div>
    <div>我是store里面的数据年龄:{{age}}</div>
    <div>我是store里面的数据身高:{{height}}</div>
  </div>
</template>
复制代码

输出结果:ecmascript

2.Getter

能够认为是 store 的计算属性,就像计算属性同样,getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被从新计算。异步

2.1mapGetter

mapGetter是getter的一个辅助函数,使用方法和mapState相似,推荐使用延展...来取值.

3.Mutation

Vuex 中的 mutation 很是相似于事件:每一个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。这个回调函数就是咱们实际进行状态更改的地方,而且它会接受 state 做为第一个参数,同步改变state的惟一方法。

在组件中经过事件方法来进行 同步改变 store中的 state,须要经过 commit提交来响应 mutation中的事件方法。

methods: {
add () {
  Store.commit('increment', { number: 10 });
},
reduce () {
  Store.commit('reduce');
}
}

复制代码

另一种写法:对象风格的提交方式

推荐使用常量替代 Mutation 事件类型

还记得在组件通讯中讲到的发布订阅方法进行组件间通讯,使用常量来定义事件类型吗?在Vuex中也是很是推荐使用此办法的,将mutation中的事件常量整合到一个文件夹mutation-type.js中,经过export方式导出.

mutation-type.js

export const ADD = 'ADD'
export const REDUCE = 'REDUCE'
复制代码

store.js中引入import {ADD,REDUCE} from './mutation-type.js'

import {ADD,REDUCE} from './mutation-type.js'
mutation:{
    [ADD](state,payload) {
        state.age += payload.number;
    },
    [REDUCE](state,payload) {
        state.age --;
    }
}
复制代码

一样的在须要的组件中引入import {ADD,REDUCE} from './mutation-type.js'

3.1 mapMutation

mapMutationmutation的辅助函数,和state相似均可以经过...扩展运算来进行直接取值。

4.Action

  • Action 提交的是 mutation,而不是直接变动状态。
  • Action 能够包含任意异步操做。

注册一个简单的Action,而且从外界传值。

Action 经过 store.dispatch方法触发,在Vue组件中:

另外的写法:参数解构

add({commit}) {
    commit('add');
}
复制代码

4.1 mapAction

mapActionaction的辅助函数,便于在Vue组件中调用action里面的事件. 在Vue组件中,能够经过解构mapAction的方式将映射

methods: {
     ...mapActions([
      'add',
      "reduce"
    ])
}
复制代码

注意此时:用mapActiono映射方法后须要传参那么须要写在事件触发的地方上

<button @click="add({number:10})">增长年龄</button>
复制代码

4.2 组合 Action

组合Action其实就是异步处理多个commit事件,能够相互调动action,借助Promise保证了数据状态的稳定性和有序性。

官方实例:

store.js

在Vue组件中:

store.dispatch('actionA').then(() => {
 
})
复制代码

在另一个 action 中能够异步提交事件:

actions: {
  actionB ({ dispatch, commit }) {
    return dispatch('actionA').then(() => {
      commit('someOtherMutation')
    })
  }
}
复制代码

推荐阅读:

MDN Promise

async / await

5.Module

当应用变得很是复杂时,store 对象就有可能变得至关臃肿,为了解决这一问题,咱们能够将store中的五种状态剥离成单个的模型,而后经过一个入口引入.通常在项目开发中在src目录下建立一个store的目录而后建立如下文件

index.js中引入全部文件,统一挂载在Vuex实例上

main.js中引入 index.js并挂载到实例Vue上

经常使用项目结构:

├── index.html
├── main.js
├── api
│   └── ... # 抽取出API请求
├── components
│   ├── App.vue
│   └── ...
└── store
    ├── index.js          # 咱们组装模块并导出 store 的地方
    ├── state.js          # 根级别的 state
    ├── actions.js        # 根级别的 action
    ├── getter.js         # 根级别的 getter
    ├── mutations.js      # 根级别的 mutation
    ├── mutations-type.js # mutation事件常数名
    └── modules
        ├── a.js       # a模块
        └── b.js       # b模块
        └── ...
    
复制代码

扫一扫下面的二维码,回复学习便可免费领取最新前端学习资料,也但愿在前端进阶的路上,咱们一块儿成长,一块儿进步!

相关文章
相关标签/搜索