Vue | 30 规模化 - 状态管理
类Flux官方实现
由于多个状态分散在不同的组件和组件直接的交互中,大型应用常常变得复杂。为了解决这个问题,Vue提供了vuex:我们有受到Elm启发的状态管理库。它甚至集成进了vue-devtools,无需配置即可进行时光旅行调试。
React 开发者参考以下信息
如果你来自React开发者,你可能想知道vuex和redux的差异,Redux是Flux生态中最流行的实现。Redux事实上无法感知视图层,所有它通过Vue的一些简单绑定很容易使用。Vuex的不同之处在于它是专门为Vue应用所设计。这允许它和Vue更好的集成,提供一个更为简单的API和提升开发体验。
简单的状态管理起步
常常被忽略的是Vue应用的原生的数据
对象的真实来源。一个Vue实例只是简单的代理访问。因此,如果你有一些通过多个实例共享的状态,你可以通过identity来共享它:
const sourceOfTruth = {}
const vmA = new Vue({
data: sourceOfTruth
})
const vmB = new Vue({
data: sourceOfTruth
})
现在无论sourceTruth
何时改变,vmA
和vmB
都将自动更新他们的视图。这些实例的子组件也可以通过this.$root.$data
访问。我们有一个唯一的数据来源,但是测试可能是一场噩梦。在任何部分任何时间我们的app都可能改变,不会留下改变的记录。
为了帮助解决这个问题,我们采用一个简单的store模式:
var store = {
debug: true,
state: {
message: 'Hello!'
},
setMessageAction(newValue) {
if (this.debug) console.log('setMessageAction triggered with', newValue)
this.state.message = newValue
},
clearMessageAction () {
if(this.debug) console.log('clearMessageAction trigged')
this.state.message = ''
}
}
注意所有store的state的状态改变都会放在store本身的actions中管理。这种中心状态管理能够更容易的理解哪种mutations类型的状态将会发生改变和他们如何被触发。现在,当有错误发生的时候,我们有一个log记录导致错误发生的原因。
此外,每一个实例/组件仍然拥有和管理自己的私有状态:
var vmA = new Vue({
data: {
privateState: {},
sharedState: store.state
}
})
var vmB = new Vue({
data: {
privateState: {},
sharedState: store.state
}
})
重要提示你绝不能在actions里面替换原始的状态对象-组件和store需要去共享应用同一个对象,mutation才能被观察。
接着我们继续延伸约定,组件不允许直接修改store实例的state,而应该分发事件执行actions去通过store,我们最终达成了Flux框架。这个框架的好处是我们能够记录所有改变的发生给到store和实现高级调试工具记录变更,快照,和历史回滚/时光旅行。
说了一圈又回到vuex,所以如果你读到这,可以尝试去试一下。