@xiaoqq
2016-10-26T07:02:10.000000Z
字数 2994
阅读 2037
Vue
定义:Vuex 是一个专门为 Vue.js 应用所设计的集中式状态管理架构。
单独使用Vue.js时,通常会把状态储存在组件的内部。对于对个组件共享状态的情况,我们通常使用事件来进行传递。这在小型系统中比较简单,但是在大中型系统中事件流会变得非常复杂。
为了更好的解决在大型应用中状态的共用问题,我们需要对组件的 组件本地状态(component local state) 和 应用层级状态(application level state) 进行区分。应用级的状态不属于任何特定的组件,但每一个组件仍然可以监视(Observe)其变化从而响应式地更新 DOM。通过汇总应用的状态管理于一处,我们就不必到处传递事件。因为任何牵扯到一个以上组件的逻辑,都应该写在这里。此外,这样做也能让我们更容易地记录并观察状态的变更(Mutation,原意为突变),甚至可以实现出华丽如时光旅行一般的调试效果。
每一个 Vuex 应用的核心就是 store(仓库)。"store" 基本上就是一个容器,它包含着你应用里大部分的 状态(即state).
所以:Vuex == 全局对象?
两者并不完全相等,Vue与全局对象有两点不同:
首先,初始化state变量和mutations
import Vuex from 'vuex'
const state = {
count: 0
}
const mutations = {
INCREMENT (state) {
state.count++
}
}
export default new Vuex.Store({
state,
mutations
})
然后,可以通过store.state 来读取 state 对象,还可以通过 dispatch 某 mutation 的名字来触发这些状态变更:
store.dispatch('INCREMENT')
console.log(store.state.count) // -> 1
一定要注意:我们是通过分发变更(mutation)的方式来改变state中的状态,而不是直接变更。
Vuex的核心概念一共有三点:State(状态)、Mutations(变更) 和 Actions(动作)
1) 用户在组件中的输入操作触发 action 调用;
2) Actions 通过dipatch(分发) mutations 来修改 store 实例的状态;
3) Store 实例的状态变化反过来又通过 getters 被组件获知。
Vuex 使用单一状态树,即用一个对象就包含了全部的应用层级状态。(每个应用仅仅只包括一个store实例)
安装 Vuex 并且将您的根组件引入 store 实例:
import Vue from 'vue'
import Vuex from 'vuex'
import store from './store'
import MyComponent from './MyComponent'
// 关键点,教 Vue 组件如何处理与 Vuex 相关的选项
Vue.use(Vuex)
var app = new Vue({
el: '#app',
// 把 store 对象提供给 “store” 选项,这可以把 store 的实例注入所有的子组件
store, // 译注:简写,等效于 store: store
components: {
MyComponent
}
})
在子组件中,通过在 vuex.getters 选项里定义的 getter 方法来读取状态:
// MyComponent.js
export default {
template: '...',
data () { ... },
// 此处为我们从 store 实例中取回状态的位置
vuex: {
getters: {
// 该 getter 函数将会把仓库的 `store.state.count` 绑定为组件的 `this.count`
count: state => state.count
}
}
}
getter 函数必须是纯函数,所以,在 getter 里不能依赖 this 关键字;
getter 函数可以返回派生状态。Vuex 状态的 getters 内部其实就是计算属性,这就意味着你能够以响应式的方式(并且更高效)地计算派生属性;
vuex: {
getters: {
filteredMessages: state => {
return state.messages.filter(message => {
return message.threadID === state.currentThreadID
})
}
}
}
可以在多组件中共享 getter 函数,这样做还可以提高运行效率;
组件永远都不应该直接改变 Vuex store 的状态,组件唯一能影响全局状态的方法就是想办法触发 mutations。
Mutations 本质上是一个事件系统:每个 mutation 都有一个 事件名 (name) 和 一个 回调函数
(handler)。
任何一个 Mutation handler 的第一个参数永远为所属 store 的整个 state 对象:
import Vuex from 'vuex'
const store = new Vuex.Store({
state: {
count: 1
},
mutations: {
INCREMENT (state) {
// 改变 state
state.count++
}
}
})
用全部大写命名 mutation 是一个惯例,方便将它和 actions 区分开。
触发mutation:store.dispatch('INCREMENT')
mutation有一点很重要就是它必须是同步函数,因为在mutation 中混合异步调用会程序很难调试。所以,所有的同步调用都放在mutation中,异步调用放在Actions中。
Actions 是用于分发 mutations 的函数
Vuex actions 的第一个参数是 store 实例,附加上可选的自定义参数:
// 最简单的 action
function increment (store) {
store.dispatch('INCREMENT')
}
// 带附加参数的 action
// 使用 ES2015 参数解构
function incrementBy ({ dispatch }, amount) {
dispatch('INCREMENT', amount)
}
在组件中使用Actions:
// 组件内部
import { incrementBy } from './actions'
const vm = new Vue({
vuex: {
getters: { ... }, // state getters
actions: {
incrementBy // ES6 同名对象字面量缩写
}
}
})