『深入 VUE』状态管理

我们在开发应用时,存在许多子组件需要响应同一个数据变化的情况,一般我们是把这个数据维护在这些子组件的共同父组件上,通过 props 向下传递,但是当项目变得复杂时,这种方法会显得很繁琐且难以维护。

当这种情况变得越来越多时,就要考虑在项目中引入状态管理了。

状态管理和普通的 props 传值有什么区别呢?

1
2
3
4
5
6
<div id="app">
<counter :count="count"></counter>
<counter :count="count"></counter>
<counter :count="count"></counter>
<button @click="count++">increment</button>
</div>

这是通过 props 传值的方式,在父组件上维护 count 属性,然后传递给三个子组件 counter,当调用方法使得 count 的值改变时,子组件自动重新渲染。

1
2
3
4
5
6
<div id="app">
<counter></counter>
<counter></counter>
<counter></counter>
<button @click="inc">increment</button>
</div>

这个实现就有点像状态管理了,父组件不再给子组件传值,counter 自己去状态仓库去获取需要的值,父组件的方法直接修改状态仓库中的属性。

以下是简单实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
const state = new Vue({
data () {
return {
count: 0
}
},
methods: {
inc () {
this.count++
}
}
})

const Counter = {
render(h) {
return h('div', state.count)
}
}

new Vue({
el: '#app',
components: {
Counter
},
methods: {
inc () {
return state.inc()
}
}
})

这样已经和 Vuex 非常接近了,可以再进一步完善:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
function createStore ({ state, mutations }) {
return new Vue({
data () {
return {
state
}
},
methods: {
commit (id) {
return mutations[id](this.state)
}
}
})
}

const store = createStore({
state: { count: 0 },
mutations: {
inc (state) {
state.count++
}
}
})

const Counter = {
render (h) {
return h('div', store.state.count)
}
}

new Vue({
el: '#app',
components: { Counter },
methods: {
inc () {
store.commit('inc')
}
}
})

以上基本就是 Vuex 核心部分的原理。