@xiaoqq
2016-10-26T07:02:10.000000Z
字数 2994
阅读 2113
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: storecomponents: {MyComponent}})
在子组件中,通过在 vuex.getters 选项里定义的 getter 方法来读取状态:
// MyComponent.jsexport 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) {// 改变 statestate.count++}}})
用全部大写命名 mutation 是一个惯例,方便将它和 actions 区分开。
触发mutation:store.dispatch('INCREMENT')
mutation有一点很重要就是它必须是同步函数,因为在mutation 中混合异步调用会程序很难调试。所以,所有的同步调用都放在mutation中,异步调用放在Actions中。
Actions 是用于分发 mutations 的函数
Vuex actions 的第一个参数是 store 实例,附加上可选的自定义参数:
// 最简单的 actionfunction 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 gettersactions: {incrementBy // ES6 同名对象字面量缩写}}})