Vuex使用

Vuex使用

      • 简介
        • 为什么要用vuex
      • Vuex 应用场景
      • 单向数据流理念
      • Vuex 有五种属性:State、Getter、Mutation、Action、Module
      • Vuex 核心
      • 流程
        • 不用Vuex会带来什么问题?

简介

Vuex 是一个专门为Vue.js应用程序开发的状态管理模式;也其实就是一个仓库管理着应用里面所有组件的状态。

为什么要用vuex

有的时候项目较大时,组件嵌套过多的时候,多组件共享同一个State会在数据传递时出现很多问题,而vuex就可以解决这些问题;

Vuex 应用场景

场景有:
(1)单页面应用
(2)组件之间的状态
(3)音乐播放
(4)登录状态
(5)加入购物车

单向数据流理念

Vuex使用_第1张图片

  • state:驱动应用的数据源(data数据);
  • view:以声明方式将state映射到视图(初始化数据和更新显示数据);
  • actions:响应在view上的用户输入导致的状态变化(多个事件函数改变数据);

Vuex 有五种属性:State、Getter、Mutation、Action、Module

Vuex 核心

vuex由一下几部分组成:

  • state
    state 管理的状态对象,就是所有组件共享的数据(初始化data);
    原理:集中存储Vue Components 中 data对象的零散数据,全局其唯一,以进行统一的状态管理,页面 显示所需的数据从该对象1中进行读取,利用 Vue 的细粒度数据响应机制来进行高效的状态更新。
// 创建一个 Counter 组件
const Counter = {
  template: `
{{ count }}
`, computed: { count () { return store.state.count } } }
  • mutations (mutation 必须是同步函数)
    直接更新 state 的方法(回调函数)的对象;
const store = new Vuex.Store({
  state: {
    count: 1
  },
  mutations: {
    increment (state) {
      // 变更状态
      state.count++
    }
  }
})

注意:不能直接调用一个 mutation hander,这个选项更像是事件注册:“当触发一个类型为 increment 的 mutation 时,调用此函数”,如果要使用一个 mutation hander,需要以相应的 type 调用 store.commit 方法:
代码是:store.commit(‘increment’)

  • actions
    1、 事件回调函数的对象,发送ajax请求与后台进行交互;
    2、原理:负责处理 Vue Components接收到的所有交互行为。包含同步和异步操作,支持多个同名方法,按照注册的顺序依次触发。想后台API请求的操作就在这个模块中机芯,包括触发其他 action 以及提交 mutation 的操作。该模块提供了 Promise 的封装,以支持 action 的链式触发。
    3、使用 action来分发(dispatch)事件通知 store 去改变,这样约定的好处是,我们能够记录所有store 中发生的 state 改变,同时实现能做到记录变更(mutation)、保存状态快照、历史回滚、时光旅行的先进的调试工具。

  • Action 类似于 mutation,不同在于以下两个方面:
    (1)Action 提交的是 mutation,而不是直接变更状态;
    (2)Action 可以包含任意的异步操作;

const store = new Vuex.Store({
 state: {
   count: 0
 },
 mutations: {
   increment (state) {
     state.count++
   }
 },
 actions: {
   increment (context) {
     context.commit('increment')
   }
 }
})

Action 函数接受一个与 store 实例具有相同方法和属性的 context 对象,因此可以调用 context.commit提交一个 mutation,或者通过context.statecontext.getters来获取 state 和 getters;

  • getters
    1、它是一个 计算属性,主要用来过滤一些数据;
    2、原理:state 对象读取方法。它被包含在了 Vue Components 通过该方法读取全局 state 对象。
    3、Getter 的返回值回根据它的依赖被缓存起来,且只有当它的依赖值发生了变化才会被重新计算。
    4、Getter 属性和 computed 计算属性差不多,就像计算属性一样,getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。

用处:
(1)如果需要从 store 中的 state 中派生出一些状态,例如对列表进行过滤并计数

computed: {
  doneTodosCount () {
    return this.$store.state.todos.filter(todo => todo.done).length
  }
}

(2)如果有多个组件需要用到此属性,我们复制这个函数,或者抽取到一个共享函数然后在多处导入它,但是哪种方式都不是很可以,而Getter 解决了这个问题。
Getter 接受 state 作为第一个参数:

const store = new Vuex.Store({
  state: {
    todos: [
      { id: 1, text: '...', done: true },
      { id: 2, text: '...', done: false }
    ]
  },
  getters: {
    doneTodos: state => {
      return state.todos.filter(todo => todo.done)
    }
  }
})

Getter 会暴露为 store.getter 对象,可以用属性的形式来进行访问这些值;

store.getters.doneTodos // -> [{ id: 1, text: '...', done: true }]
  • mudules
    原理:状态改变操作方法。是 Vuex 修改 state 的唯一推荐方法,其他修改方式在严格模式下将会报错的,该方法只能进行同步操作,且方法名只能全局唯一。操作之中会有一些 hook 暴露出来,以进行 state 的监控等。
    由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变的非常复杂时, store 对象就有可能会变得复杂,而为了解决这个问题,Vuex 允许我们将 store 分割成模块 (module),每个模块拥有自己的 state、mutation、action、getter、将嵌套子模块从上至下进行同样方式的分割;
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 的状态
  • Vue Components:Vue组件,在HTML页面上,负责接收用户操作等交互行为,执行dispatch方法触发对应 action 进行回应。
  • store
    在 main.js 配置后会生成一个 $store 属性,它就是 store 对象,其中有属性 state,getters,方法 dispatch(actionName, data):分发调用 action;

流程

Vuex使用_第2张图片
流程:Vue组件接收交互行为,调用 dispatch 方法触发 action 相关处理,如果页面状态需要改变,则调用 commit 方法提交 mutation 修改 state,通过 getters 获取 state 新值,重新渲染 Vue Components,界面会随之更新。

不用Vuex会带来什么问题?

1、可维护性会下降,如果想要修改数据,要维护三个地方;
2、可读性会下降,因为一个组件里的数据,根本看不出来是从哪来的;
3、增加耦合,大量的上传会派发,会让耦合性大大的增加,本来Vue 用Component就是为了减少耦合,如果不用Vuex的话,就会和组件化的初衷相反;

请多多指教~!

你可能感兴趣的:(vue)