Vue从入门到精通 B站(128-140)

129. Vuex:概念和作用解析

Vuex是做什么的?

  • 官方解释:Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。
    • 它采用***集中式存储管理***应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
    • Vuex也集成到 Vue 的官方调试工具devtools extension,提供了诸如零配置的time-travel调试、状态快照导入导出等高级调试功能。

管理什么状态呢?

130. Vuex:单界面到多界面状态管理切换

单界面的状态管理

State:不用多说,就是我们的状态。(姑且可以当做就是data中的属性)
View:视图层,可以针对State的变化,显示不同的信息。
Actions:这里的Actions主要是用户的各种操作:点击、输入等等,会导致状态的改变。

单界面状态管理的实现

多界面状态管理

  • 全局单例模式(大管家)
    • 我们现在要做的就是将共享的状态抽取出来,交给我们的大管家,统一进行管理。
    • 之后,你们每个试图,按照我规定好的规定,进行访问和修改等操作。
    • 这就是Vuex背后的基本思想。

Vuex状态管理图例

131. Vuex:devtools和mutations

简单的案例

chrome网上应用商店搜索:vue.js devtools
实现一下之前简单的案例:

存放Vuex代码:创建一个文件夹store,并且在其中创建一个index.js文件,在index.js文件中写入如下代码。

挂载到Vue实例中

  • 其次,让所有的Vue组件都可以使用这个store对象
    • 来到main.js文件,导入store对象,并且放在new Vue中
    • 这样,在其他Vue组件中,我们就可以通过this.$store的方式,获取到这个store对象了

使用Vuex的count

  • 这就是使用Vuex最简单的方式了。
  • 来对使用步骤,做一个简单的小结:
    1. 提取出一个公共的store对象,用于保存在多个组件中共享的状态
    2. 将store对象放置在new Vue对象中,这样可以保证在所有的组件中都可以使用到
    3. 在其他组件中使用store对象中保存的状态即可
      • 通过this.$store.state.属性的方式来访问状态
      • 通过this.$store.commit(‘mutation中方法’)来修改状态
  • 注意事项:
    • 我们通过提交mutation的方式,而非直接改变store.state.count。
    • 这是因为Vuex可以更明确的追踪状态的变化,所以不要直接改变store.state.count的值。

132. Vuex:state单一状态树的理解

Vuex核心概念

  • State
  • Getters
  • Mutation
  • Action
  • Module

State单一状态树

133. Vuex:getters使用详解

Getters基本使用

有时候,我们需要从store中获取一些state变异后的状态,比如下面的Store中:

  • 获取学生年龄大于20的个数

我们可以在Store中定义getters

Getters作为参数和传递参数

如果我们已经有了一个获取所有年龄大于20岁学生列表的getters, 那么代码可以这样来写

getters默认是不能传递参数的, 如果希望传递参数, 那么只能让getters本身返回另一个函数

  • 比如上面的案例中,我们希望根据ID获取用户的信息

代码:

store/index.js:

import Vue from 'vue'
import Vuex from 'vuex'

import mutations from './mutations'
import actions from './actions'
import getters from './getters'
import moduleA from './modules/moduleA'

// 1.安装插件
Vue.use(Vuex)

// 2.创建对象

const store = new Vuex.Store({
  state: {
    counter: 1000,
    students: [
      { id: 110, name: 'why', age: 18 },
      { id: 111, name: 'kobe', age: 24 },
      { id: 112, name: 'james', age: 30 },
      { id: 113, name: 'curry', age: 10 }
    ],
  },
  mutations: {
    // 方法
    increment(state) {
      state.counter++;
    },
    decrement(state) {
      state.counter--;
    }
  },
  actions,
  getters: {
    powerCounter(state) {
      return state.counter * state.counter
    },
    more20stu(state) {
      return state.students.filter(s => s.age > 20)
    },
    more20stuLength(state, getters) {
      return getters.more20stu.length
    },
    moreAgeStu(state) {
      return function (age) {
        return state.students.filter(s => s.age > age)
      }

      // 不推荐下面写法,阅读性太差
      /* return age => {
        return state.students.filter(s => s.age > age)
      } */
    }
  },

  modules: {
    a: moduleA
  }
})

// 3.导出store独享
export default store


// 对象的解构
const obj = {
  name: 'why',
  age: 18,
  height: 1.88,
  address: '洛杉矶'
}

const { name, height, age } = obj;

App.vue:




  

HelloVuex.vue:






结果:

134. Vuex:mutations的携带参数

Mutation状态更新

Vuex的store状态的更新唯一方式:提交Mutation

  • Mutation主要包括两部分:
    • 字符串的事件类型(type)*
    • 一个回调函数(handler),该回调函数的第一个参数就是state。
      mutation的定义方式:

通过mutation更新:

Mutation传递参数

Vuex的store状态的更新唯一方式:提交Mutation

  • Mutation主要包括两部分:
    • 字符串的事件类型(type)
    • 一个回调函数(handler),该回调函数的第一个参数就是state
      mutation的定义方式:

通过mutation更新:

Mutation传递参数

  • 在通过mutation更新数据的时候, 有可能我们希望携带一些额外的参数

    • 参数被称为是mutation的载荷(Payload)
      Mutation中的代码:
  • 但是如果参数不是一个呢?

    • 比如我们有很多参数需要传递.
    • 这个时候, 我们通常会以对象的形式传递, 也就是payload是一个对象
    • 这个时候可以再从对象中取出相关的信息

135. Vuex:mutations的提交风格

上面的通过commit进行提交是一种普通的方式
Vue还提供了另外一种风格, 它是一个包含type属性的对象:

Mutation中的处理方式是将整个commit的对象作为payload使用, 所以代码没有改变, 依然如下:

136. Vuex:数据的响应式原理

Mutation响应规则

Vuex的store中的state是响应式的, 当state中的数据发生改变时, Vue组件会自动更新

  • Vuex对应的规则:
    • 提前在store中初始化好所需的属性.
    • 当给state中的对象添加新属性时, 使用下面的方式:
      • 方式一: 使用Vue.set(obj, ‘newProp’, 123)
      • 方式二: 用心对象给旧对象重新赋值
        一个例子:

当我们点击更新信息时, 界面并没有发生对应改变。
让它改变的方法:
下面代码的方式一和方式二,都可以让state中的属性是响应式的

137. Vuex:mutations的类型常量

Mutation常量类型 – 概念

项目过大时,可以使用常量替代Mutation事件的类型
创建一个文件: mutation-types.js, 并且在其中定义我们的常量.
定义常量时, 我们可以使用ES2015中的风格, 使用一个常量来作为函数的名称

138. Vuex:actions的使用详解

Mutation同步函数

  • 通常情况下, Vuex要求我们Mutation中的方法必须是同步方法.
    • 主要的原因是当我们使用devtools时, 可以devtools可以帮助我们捕捉mutation的快照.
    • 但是如果是异步操作, 那么devtools将不能很好的追踪这个操作什么时候会被完成
      因此,通常情况下, 不要再mutation中进行异步的操作

Action的基本定义

某些情况, 我们确实希望在Vuex中进行一些异步操作, 比如网络请求。此时就用到了action
Action类似于Mutation, 但是用来代替Mutation进行异步操作的
Action的基本使用代码如下:

  • context:
    • context是和store对象具有相同方法和属性的对象.
    • 也就是说, 我们可以通过context去进行commit相关的操作, 也可以获取context.state等.
    • 但是注意, 这里它们并不是同一个对象(后面学习Modules再具体说)

Action的分发

在Vue组件中, 如果我们调用action中的方法, 那么就需要使用dispatch:

同样的, 也是支持传递payload:

Action返回的Promise

在Action中, 我们可以将异步操作放在一个Promise中, 并且在成功或者失败后, 调用对应的resolve或reject:

139. Vuex:modules的使用详解

认识Module

  • Module是模块的意思, 为什么在Vuex中我们要使用模块呢?
    • Vue使用单一状态树,那么也意味着很多状态都会交给Vuex来管理.
    • 当应用变得非常复杂时,store对象就有可能变得相当臃肿.
    • 为了解决这个问题, Vuex允许我们将store分割成模块(Module), 而每个模块拥有自己的states、mutations、actions、getters等
      组织模块的代码:

Module局部状态

  • 上面的代码中, 我们已经有了整体的组织结构, 下面我们来看看具体的局部模块中的代码如何书写.
    • 我们在moduleA中添加state、mutations、getters
    • mutation和getters接收的第一个参数是局部状态对象

注意:虽然,我们的doubleCount和increment都是定义在对象内部的。但是在调用的时候,依然是通过this.$store来直接调用的。

Actions的写法

actions的写法呢? 接收一个context参数对象
局部状态通过 context.state 暴露出来,根节点状态则为 context.rootState

如果getters中也需要使用全局的状态, 可以接受更多的参数

140. Vuex:store文件夹的目录组织

项目结构

当我们的Vuex帮助我们管理过多的内容时, 好的项目结构可以让我们的代码更加清晰

你可能感兴趣的:(Vue从入门到精通 B站(128-140))