Libx

VUe全家桶之VueX

字数统计: 1,645阅读时长: 6 min
2017/08/13 Share

如果你要使用Vue构建一个相对比较复杂的项目,Vuex在你的项目将占有非常重要的地位。

暑期留校总结系列<三>——VueX

Vuex是什么?

老规矩,首先还是来放一波官方文档地址:地址在此

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

他的设计思想应该是类似于react中的redux的,它所实现的功能也是和redux的作用是类似的,都是对应用程序总的各种状态抽离到这个系统外层来统一进行管理,放置了数据流的混乱以及状态的不可控性。我觉得Vue对于状态的管理是非常看重的,父子组件通信中数据的单项传递也是为了增强维护数据的可控性,避免你在使用的时候因为状态的混乱而崩溃。状态的管理是非常需要重视的,因为在复杂的情况下,很有可能你不找不到你的数据在哪里发生了改变,被谁改变,然后你将花上很长时间来debug,,(反正我是遇到了。。)

在我的实际项目中,起初并未使用Vuex来抽离所有状态并作统一的状态管理,起初认为在父子组件之间的通信完全不需要借助第三方的工具,而同级组件之间的通信完全可以使用Event Bus来实现。但是我前期还是低估了这个项目所需要传递的数据和需要管理的状态,,(因为这个项目并不能开源,,所有,很遗憾)在前期的编写过程中还是比较可以的,但是在后来需要管理的数据越来越多,数据流越来越混乱,甚至有点想打人。然后就果断上了VUEX,之后就舒服多了。

[caption id=”” align=”aligncenter” width=”548”] 一般的单向数据流[/caption]

 

 

[caption id=”” align=”aligncenter” width=”701”] 复杂情况[/caption]

 

有一句话我非常的认同,这句话也写在了官方文档的第一页:Flux 架构就像眼镜:您自会知道什么时候需要它。

Let’s do it

首先安装一波

NPM

npm install vuex --save

在一个模块化的打包系统中,您必须显式地通过 Vue.use() 来安装 Vuex:

import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)

Vuex的组成:

vuex主要是由这几部分组成

  • State
  • Getters
  • Mutations
  • Actions

State:顾名思义,状态,Vuex 使用 单一状态树,用一个对象就包含了全部的应用层级状态。至此它便作为一个『唯一数据源(SSOT)』而存在。这也意味着,每个应用将仅仅包含一个 store 实例。单一状态树让我们能够直接地定位任一特定的状态片段,在调试的过程中也能轻易地取得整个当前应用状态的快照。具体的实例不再放出。


Getters;同样的,get?获取东西的一个东西。

有时候我们需要从 store 中的 state 中派生出一些状态,比如需要进行的一些过滤,排序,计数等。如果有多个组件需要用到,那么重复的在各个组件中使用将不是很理想,Vuex 允许我们在 store 中定义『getters』(可以认为是 store 的计算属性)。Getters 接受 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)
}
}
})

Getters 会暴露为 store.getters 对象:

store.getters.doneTodos[{ id: 1, text: '...', done: true }]

Getters 也可以接受其他 getters 作为第二个参数:

getters: {
doneTodosCount: (state, getters)
{
return getters.doneTodos.length
}
}
store.getters.doneTodosCount1

我们可以很容易地在任何组件中使用它:

computed: {
doneTodosCount () {
return this.$store.getters.doneTodosCount
}
}

相比之下,可能getters用的不是非常的多?但是他非常有用,他为很多尴尬的场景提供了非常优雅的解决方案。


mutations和actions联系的非常的紧密:因为在Vuex中需要使用action来触发一个mutation,由mutation来触发状态的改变,也就是说,action并不能改变state,他只是发送一个更改状态的通知,然后将数据传过去,最终是由mutation来进行改变。

Action 类似于 mutation,不同在于:

  • Action 提交的是 mutation,而不是直接变更状态。
  • Action 可以包含任意异步操作。
    mutation 必须同步执行?Action 就不受约束!我们可以在 action 内部执行异步操作

    非常重要!

     


    实际应用:

    Vuex 并不限制你的代码结构。但是,它规定了一些需要遵守的规则:

  1. 应用层级的状态应该集中到单个 store 对象中。
  2. 提交 mutation 是更改状态的唯一方法,并且这个过程是同步的。
  3. 异步逻辑都应该封装到 action 里面。
    只要你遵守以上规则,如何组织代码随你便。在实际的应用中,按照你的项目大小,你可以选择使用一个单独的store.js来存放所有的state,getters,mutations,actions,当然如果你的项目足够大的话,你也可以使用模块化的方式,(对于modules。。没什么特别的体会,就是拆一拆?)将他们分别大卸八块,下面是项目结构示例:
    ├── index.html
    ├── main.js
    ├── api
    │ └── ... 抽取出API请求
    ├── components
    │ ├── App.vue
    │ └── ...
    └── store
    ├── index.js 我们组装模块并导出 store 的地方
    ├── actions.js 根级别的 action
    ├── mutations.js 根级别的 mutation
    └── modules
    ├── xxx.js
    └── xxxx.js

一些总结:

事实上,我们可以看到,当然如果你写了的话会有更深的体会,在实际的操作中,如果你使用了vuex,相对复杂的流程使你只需更改一个true或false都要走一堆流程,虽然这是规范的操作方式,但是这确实有些不够优雅。。所以我做了一个测试,在组件中,使用同行this.$store.state.xxx=xxxx是可以直接改变state中的状态的。。但是,慎用。。除非你这个状态真的只是这么简单,还有你不怕被review你代码的boss打。(逃。。)

CATALOG
  1. 1. 暑期留校总结系列<三>——VueX
    1. 1.1. Vuex是什么?
    2. 1.2. Let’s do it
    3. 1.3. 首先安装一波
      1. 1.3.1. NPM
    4. 1.4. Vuex的组成:
    5. 1.5. 实际应用:
    6. 1.6. 一些总结: