vuex的实现——为什么需要使用全局状态管理(一)
这段时间结合vue及vuex的知识来阅读vuex源码,收获挺多的。因此把阅读过程中我对vuex的理解,大到一个类,一个函数,小到一个变量的使用,都记录下来。一千个读者就有一千个哈姆雷特,在阅读过程中,由于本人功力,经验原因,难免有理解不到位的地方,欢迎多多指教。在实际项目中,我们经常遇到多个组件视图依赖同一个状态,并且其中的一个组件更改这个状态时,其余依赖了该状...
这段时间结合vue及vuex的知识来阅读vuex源码,收获挺多的。因此把阅读过程中我对vuex的理解,大到一个类,一个函数,小到一个变量的使用,都记录下来。一千个读者就有一千个哈姆雷特,在阅读过程中,由于本人功力,经验原因,难免有理解不到位的地方,欢迎多多指教。
在实际项目中,我们经常遇到多个组件视图依赖同一个状态,并且其中的一个组件更改这个状态时,其余依赖了该状态的组件视图也要相应的更新。假设我们要实现一个定时器应用,组件树如下:
这里根组件main.js,以及后代组件app.vue,counter.vue,counterItem.vue需要共享状态count。当状态count更新时,所有依赖count的组件都必须响应更新。为了实现根组件以及后代组件能响应count的变化,我们需要把数据count放在根组件main.js的data属性中,然后通过props属性一层一层往下传递给后代组件,这样当根组件的count属性变化时,其后代中依赖了count的组件也会相应的更新。为了实现任何依赖count的组件更改count时,其他组件也能够响应更新,我们需要在根组件中定义一个方法,并且把这个方法一层一层地往下传递给后代组件。当需要在后代组件中更新count时,可通过emit方法向父级组件触发更新事件,这样一级一级往上传递emit事件,直到触发根组件main.js中的更新状态方法。可以看出,当应用越来越复杂,组件层级越来愈深时,这种一层一层往下传递data,一层一层往上触发事件的方式是繁琐、低效同时维护极其麻烦的。因此我们需要一种全局的状态管理容器,任何组件需要用到里面的状态时就去容器读取,需要变更状态时,就向容器提交变更。这样不管应用多复杂,组件树层级多深,组件都能直接访问里面的状态。而我们要做的只是维护全局的状态管理。
这一节的源码如下,源码对应图1的组件树:
main.js
import Vue from 'vue'
import App from './App'
Vue.config.productionTip = false
new Vue({
el: '#app',
data () {
return {
count: 1
}
},
components: { App },
template: '<App :count="count" @increment = "increment"/>',
methods: {
increment () {
this.count++
}
}
})
App.vue
<template>
<div id="app">
app.vue
<div>{{ count }}</div>
<div @click="$emit('increment')">increment in app.vue</div>
<Counter :count="count" @increment="$emit('increment')"/>
</div>
</template>
<script>
import Counter from './components/counter'
export default {
props: ['count'],
components: {
Counter
}
}
</script>
counter.vue
<template>
<div id="counter">
counter.vue
<div>{{ count }}</div>
<div @click="$emit('increment')">increment in counter.vue</div>
<CounterItem :count="count" @increment="$emit('increment')"/>
</div>
</template>
<script>
import CounterItem from './counterItem'
export default {
props: ['count'],
components: {
CounterItem
}
}
</script>
counterItem.vue
<template>
<div id="counter-item">
counter-item
<div>{{ count }}</div>
<div @click="$emit('increment')">increment in counterItem.vue</div>
</div>
</template>
<script>
export default {
props: ['count']
}
</script>
更多推荐
所有评论(0)