[TOC]
Vuex起步
每一个 Vuex 应用的核心就是 store(仓库)。
"store" 基本上就是一个容器,它包含着你的应用中大部分的状态(state)。
Vuex 和单纯的全局对象有以下两点不同:
- Vuex 的状态存储是响应式的。
当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。 - 你不能直接改变 store 中的状态。
改变 store 中的状态的唯一途径就是显式地提交(commit) mutations。
这样使得我们可以方便地跟踪每一个状态的变化,从而让我们能够实现一些工具帮助我们更好地了解我们的应用。
最简单的 Store
假设一个微小的应用,有一个标签显示数字,两个按钮分别做数字的加一和减一的操作。用户界面看起来是这样的:
使用vue的话,就是这样:
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<div id="app">
<p>{{count}}
<button @click="inc">+</button>
<button @click="dec">-</button>
</p>
</div>
<script>
new Vue({
el:"#app",
data () {
return {
count: 0
}
},
methods: {
inc () {
this.count++
},
dec () {
this.count--
}
}
})
</script>
预览:
整个代码结构非常清晰,代码是代码,数据是数据。代码就是放在methods数组内的两个函数inc、dec,被指令@click关联到button上。而data内返回一个属性count,此属性通过{{count}}绑定到标签p内。
现在来看看,同样的demo app,使用vuex完成的代码的样子
安装 Vuex 之后,让我们来创建一个 store。创建过程直截了当——仅需要提供一个初始 state 对象和一些 mutations:
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vuex@2.0.0"></script>
<div id="app">
<p>{{count}}
<button @click="inc">+</button>
<button @click="dec">-</button>
</p>
</div>
<script>
// 如果在模块化构建系统中,请确保在开头调用了 Vue.use(Vuex)
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
inc: state => state.count++,
dec: state => state.count--
}
})
const app = new Vue({
el: "#app",
computed: {
count () {
return store.state.count
}
},
methods: {
inc () {
store.commit("inc")
},
dec () {
store.commit("dec")
}
}
})
</script>
预览:
我们先看到有哪些重要的变化:
- 新的代码添加了对vuex脚本的依赖。这是当然的,因为你需要使用vuex的技术,当然需要引用它
- methods数组还是这两个方法,这和demo1是一样的;但是方法内的计算逻辑,不再是在函数内进行,而是提交给store对象!这是一个新的对象!
- count数据也不再是一个data函数返回的对象的属性;而是通过计算字段来返回,并且在计算字段内的代码也不是自己算的,而是转发给store对象。再一次store对象!
就是说,之前在vue实例内做的操作和数据的计算现在都不再自己做了,而是交由对象store来做了。
store对象是Vuex.Store的实例。
在store内有分为state对象和mutations对象,其中的state放置状态,mutations则是一个会引发状态改变的所有方法。
正如我们看到的,目前的state对象,其中的状态就只有一个count。
而mutations有两个成员,它们参数为state,在函数体内对state内的count成员做加1和减1的操作。
再次强调,我们通过提交 mutation 的方式,而非直接改变 store.state.count,是因为我们想要更明确地追踪到状态的变化。这个简单的约定能够让你的意图更加明显,这样你在阅读代码的时候能更容易地解读应用内部的状态改变。此外,这样也让我们有机会去实现一些能记录每次状态改变,保存状态快照的调试工具。有了它,我们甚至可以实现如时间穿梭般的调试体验。
由于 store 中的状态是响应式的,在组件中调用 store 中的状态简单到仅需要在计算属性中返回即可。触发变化也仅仅是在组件的 methods 中提交 mutations。