1、Vuex的基本介绍

1.1Vuex是做什么的

官方解释:Vuex是一个专为Vue.js应用程序开发的状态管理模式。

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

状态管理到底是什么?

  • 简单的将其看成把需要多个组件共享的变量全部存储在一个对象里。
  • 然后,将这个对象放在顶层的Vue实例中,让其他组件可以使用。

Vuex可以做到响应式

1.2管理什么状态?

  • 可用于管理登录状态,用户名称、头像、地理位置,商品的收藏,购物车的物品等。
  • 这些状态信息,可以放在统一的地方,对它进行保存和管理,而且它们是响应式的。

1.3为什么组件不能直接修改store状态

  • 直接修改无法跟踪state的状态修改
  • 数据响应式
  • Devtools:Vue开发的浏览器插件,帮忙记录每次修改state的状态
  • 同步: 组件 -> mutations -> state (actions可省略)
  • 异步: 组件 ->actions(执行异步操作)-> mutations -> state

2、Vuex核心概念

  • State:保存共享状态的地方,单一状态树
  • Getters:类似组件中的计算属性
  • Mutation:修改State状态
  • Action:主要做一些异步操作
  • Module:专门划分一些模块,针对不同模块,再对相关数保存

2.1state单一状态树

  • 解释:单一数据源
  • 方便管理

2.2Getters的基本使用

//在store中定义
getters:{
  powerCounter(state) { //counter的平方
      return state.counter * state.counter
  },
  more20stu(state) { // 返回年龄大于20的学生
      return state.students.filter(s => s.age > 20)
  more20stuLength(state, getters) { // 获取年龄大于20的学生数量 
      return getters.more20stu.length
  },
  moreAgeStu(state) {
      return function (age) { //调用传参
          return state.students.filter(s => s.age > age)
      }
  }
}

// 数据调用
$store.getters.powerCounter
//传递参数
$store.getters.moreAgeStu(age) //传递参数

2.3Mutations状态更新

1、Vuex的store状态更新的唯一方式:提交Mutations

2、Mutations主要包括两部分:1、字符串的事件类型(type);2、一个回调函数(handler),该回调函数的第一个参数就是state

3、Mutations传递参数,参数被称为是mutation的载荷(Payload)

// 带参
mutations: {
    addCount(state, count) {
        state.counter += count
    }
}

this.$store.commit('addCount', count)

4、mutations的提交风格

// 方式一:普通提交风格
this.$store.commit('addCount', count)

// 方式二,包含type属性的对象
this.$store.commit({
  type: 'addCount',
  count
})

addCount(state, payload) {
    state.counter += payload.count
}

5、Mutations的响应规则

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

  • 这就要求我们必须遵守一些Vuex对应的规则:

    (1)、提前在store中初始化所需的属性;

    (2)、当给state中的对象添加新属性时,使用下面的方式

  • 方式一:使用Vue.set(obj, 'newProp', 123)

Vue.set(state.info, 'height', 1.8)
  • 方式二:用新对象给旧对象重新赋值
state.info = {...state.info, 'height', 1.88}
  • Vue.delete(obj, 'propName')// 删除属性,响应式

6、Mutations的类型常量

  • 为了使用者花费大量的精力去记住方法名,甚至是多个文件间来回切换,查看方法名称,避免写错方法名
import {INCREMENT} from '文件路径'
mutations: {
    ['test'](state) { //可使用这种方式定义方法名

    },
    [INCREMENT](state) { //使用常量名作为方法名

    }
}
export default //使用default导出的对象才能使用:import 自定义名字 from ‘文件路径’
export const A //只能使用 import {A} from '文件路径'

7、mutations同步函数

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

2.4Actions的使用详解

  • 异步方法在actions中实现
mutations; {
    updateInfo( {
        // 同步方法
    })
}
actions: {
    // context上下文, payload参数
    aUpdateInfo(context, payload) {
        //异步方法
        // 方式一
        setTimeout(() => {
           context.commit('updateInfo') // 调用mutations中的updateInfo
           console.log(payload.message) //调用参数
           payload.success() // 调用回调
        }, 1000)

        // 方式二
        return new Promise((resolve, reject) => {
          setTimeout(() => {
           context.commit('updateInfo') // 调用mutations中的updateInfo
           console.log(payload)
           resolve('11111')
          }, 1000)
        })
    }
}

// 调用
updateInfo() {
    // 调用action方式一
    this.$store.dispatch('aUpdateInfo', {
      message: '我是payload',
      success: () => {
          console.log('action里面已经完成')
      }
    }) //调用actions中的aUpdateInfo方法

    //调用action方式二
    this.$store
    .dispatch('aUpdateInfo', '我是payload')
    .then(res => {
      console.log('里面完成了提交')  
      console.log(res)
    })
} 

2.5modules的使用详解

  • Vue使用单一状态树,意味着很多状态都会交给Vuex来管理
  • 当应用变得非常复杂时,store对象就有可能变得相当臃肿
  • 为了解决这个问题,Vuex允许将store分割成模块(Module),而每个模块拥有自己的state、mutations、actions、getters
const moduleA = {
  atore: {
      name: '我是a模块'
  },
  mutation: {
  },
  actions: {
  },
  getters: {
  }  
}
modules: {
    a: moduleA
    b: {
       // 省略... 
    }
}

//页面调用
$store.state.a.name
this.$store.commit('updateInfo', 'list')

名词解释:对象的解构,数组的结构

// 对象的解构
const obj = {
    name: 'chuan'
    age: 2,
    height: 1.88
}

const a = {age, height, name} = obj // 根据名字对应,不是根据顺序

// 数组的解构
const names = ['kobe', 'curry', 'james']

const allNames[name1, name2, name3] = names