上手Vue三个月,谈谈自己对Vuex的理解.(结合文档与实际项目)
Flux基本了解
概念
Flux是Facebook用于构建客户端Web应用程序提出的应用程序架构。它在React的视图组件中使用单向数据流。它更多的是一种模式,而不是一个正式的框架,您可以立即开始使用Flux,而不需要大量的新代码。
Flux应用有三个主要的概念: Dispatcher , Stores , Views(React 组件) .不要把这三个概念与传统的MVC(Model-View-Controller)相混淆.Flux避开MVC,有利于单向数据流。
Structure and Data Flow
Flux中的单项数据流
单向数据流是Flux模式的核心,Dispatcher , Stores , Views是具有不同输入和输出的独立节点。Action是包含新数据和识别类型属性的简单对象.
View: 视图层
Action(动作):视图层发出的消息(比如mouseClick)
Dispatcher(派发器):用来接收Actions、执行回调函数
Store(数据层):用来存放应用的状态,一旦发生变动,就提醒Views要更新页面
所以上图可以理解为:
Action触发Dispatcher中的回调函数,导致Store中的状态发生变化,最终影响View视图重新渲染.
另外一种模式: 见下图
视图View在与用户的交互过程中产生一个新的Action. Action被Dispatcher接收.触发Dispatcher中的回调函数执行,改变了Store中状态,Store状态更新,导致View层重新渲染.
Flux架构所有数据都是单项流动的.
这里只是为了更好理解Vuex,了解下基本的概念.
具体学习Flux
Vuex
以在Vuex中存储用户登陆后信息模块为例.
目录结构
|-- store # Vuex的根目录
|-- modules #可以理解为该文件夹下每个js模块就是一个store
|-- user.js #demo: 用户登陆后的信息模块
|-- index.js # 对外导出store
|-- mutation-types.js #抽离出来的存放各种 mutation 事件类型的模块
先上代码:
// index.js
import Vue from 'vue'
import Vuex from 'vuex'
import user from './modules/user'
Vue.use(Vuex)
const debug = process.env.NODE_ENV !== 'production' && process.env.NODE_ENV !== 'production-runtime'
export default new Vuex.Store({
modules: {
user
},
strict: debug,
plugins: debug ? [createLogger()] : []
})
// mutation-types.js
// User
export const SET_USER_INFO = 'SET_USER_INFO'
// user.js
import * as types from '../mutation-types'
// initial state
const state = {
userInfo: {}
}
// getters
const getters = {
getUserInfo: state => state.userInfo
}
// actions
const actions = {
setUserInfo ({commit}, user) {
commit(types.SET_USER_INFO, user)
}
}
// mutations
const mutations = {
[types.SET_USER_INFO] (state, userInfo) {
state.userInfo = userInfo
}
}
export default {
state,
getters,
actions,
mutations
}
// main.js 这里只引入部分代码
import store from './store'
const app = new Vue({
...
store
}).$mount('#app')
// 只涉及部分代码
// 与后端API的HTTP交互
// 当前demo场景就是用户登陆了,一个封装的login方法
// getApiJson: 封装获取数据的方法
login (creds) {
return getApiJson(LOGIN_API, creds)
.then((res) => {
if (res) {
// user: 存储用户信息的对象
let user = {
loginName: res.user.loginName,
avatarId: res.user.avatarId,
employeeId: res.user.typeInstanceId,
userId: res.id,
name: res.user.name,
token: res.token
}
// 通过store去分发setUserInfo(Action)+载荷user
store.dispatch('setUserInfo', user)
this.user.authenticated = true
// 存储token与用户信息在sessionStorage
sessionStorage.token = res.token
sessionStorage.user = JSON.stringify(user)
}
})
},
可能对于没接触过Vuex的看完这些代码有点小蒙,现在结合Vuex的概念与思想.
什么是Vuex?
Vuex是为Vue定制的一种状态管理模式,其核心思想借鉴了Flux、Redux、和 The Elm Architecture.
或者你也可以简单理解为Vuex,它是一个全局的(意味中对外都可以访问),单例模式的管理状态.Vue应用中任何组件都可以获取Vuex中的状态(数据)以及去触发Vuex的行为.
为什么需要Vuex?
相信使用Vue或者其他单页应用框架的大多数碰到这种情况.
如果我们通过props和事件在爷/父/孙进行通信,在多层组件嵌套的情况下,且不说行不行的通,代码过于臃肿,耦合过深,不利于维护和扩展.
这个时候就需要Vuex了,把需要A中的state存储起来,大家需要的直接从Vuex获取.并且Vuex是响应式的,动态更新.
当然也不是说什么状态都怼到Vuex,视具体业务情况.能够通过props/事件进行通信的,或者$refs(官网不建议过多使用)获取state的就不需要用Vuex了.
Vuex的核心概念
单项数据流
Vue是基于数据驱动.
理解
View : 视图(Vue组件)
State:状态(一般是一个对象,存储我们需要的数据信息)
Actions: 通过提交mutation,来改变State
用户与视图交互,触发Actions,执行Actions的回调,提交mutation,导致State发生改变,State重新渲染视图.
State
- 单一状态树
我理解其实就是说State就是一个对象,包含你需要的应用状态(数据). 当然你要先对其进行一个初始化.
- 为什么我们可以在每个组件获取Vuex
Vuex 通过 store 选项,从根组件『注入』到每一个子组件中(需调用 Vue.use(Vuex)).其实就是在new Vue()传入store,前面代码已经有就不重复贴了.
Getters
我们可以理解Getters为Store的计算属性,通过Getters可以对Store中State做处理.Getters 接受 state 作为其第一个参数,也可以接受其他 getters 作为第二个参数.
- 在子组件去获取Vuex的状态
在计算属性中通过mapGetters辅助函数.将 store 中的 getters 映射到局部计算属性
computed: {
...mapGetters([
'getUserInfo'
])
},
Mutations
几个重要点:
- 更改 Vuex 的 store 中的State的唯一方法是提交(commit) mutation
- 每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler),在回调函数中处理state.接受 state 作为第一个参数.
- 不能直接调用一个 mutation handler,只可以通过commit(type)去触发一个 mutation handler.
- commit()可以接受除state外的额外的参数,该参数称为mutation的载荷.载荷一般是包含多个字段(key)的对象.
- 使用常量替代 Mutation 事件类型.最好就是把这些常量放在单独的文件中,统一管理,如我demo中的mutation-types.js.
Actions
- Action 可以包含任意异步操作
- Action里面实际执行的是提交mutation
- 通过store.dispatch()分发Actions.
- Actions 同样支持载荷方式和对象方式进行分发
Modules
Vuex 允许把store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter .这样更加方便管理,细粒度化.
对于模块内部的 mutation 和 getter,接收的第一个参数state是模块的局部状态对象。
更加详细的具体见官网文档:Vuex
最后理解这张图收官:
1. State渲染Vue组件(视图)
2. Vue组件(视图)与用户交互过程中分发(dispatch)Actions
3. Actions执行相应的回调,commit(type)
4. 触发Mutations的事件,更改Store中的State.
5. State发生变化,重新刷新视图Vue组件
6. Actions在与后台API进行HTTP交互时候触发.
7. Devtools: 一个Vue 的官方调试工具
有些点还没有领会,后面再改.




