<body>
<div id="app">
<p ref="msg">{
{name}}</p>
<button @click="change">点我</button>
</div>
</body>
</html>
<script src="./vue.js"></script>
<script>
new Vue({
el: '#app',
data(){
return {
count: 0,
firstName: 'yang',
lastName: 'rui'
}
},
computed: {
name(){
if(this.count > 0){
return this.firstName + this.lastName
}
return 'please click me'
}
},
methods: {
change(){
this.count ++
},
changeLastName(){
this.lastName= 'ai'
}
}
})
</script>
computed初始化以及更新步骤
- 初始化 initComputed 为计算属性注册watcher,以及设置getter
- render时候取值,触发getter,执行evaluate 方法取值,取值过程中为计算属性依赖的属性添加依赖,也就是为count添加依赖,这里的依赖是computedWatcher,接着执行depend方法为count添加依赖,这里添加的是渲染watcher
- 执行change方法,更新count的值时,会触发它的setter,通知watcher的update方法,如果是computedWatcher就执行this.dirty=true;如果是渲染watcher就执行queueWatcher,更新视图
- 更新视图过程中,执行到render,又会取name的值,这时候如果dirty为true,就重新计算属性值,如果为false就会从缓存中拿到值,为true的情况是计算属性依赖的属性值发生了变化,否则为false
- 所以得出一个结论:只有计算属性依赖的值发生了变化,才会重新计算,否则直接在缓存中拿值,不会重新计算
var computedWatcherOptions = { lazy: true };
function initComputed (vm, computed) {
var watchers = vm._computedWatchers = Object.create(null);
var isSSR = isServerRendering();
for (var key in computed) {
// 每个属性对应的方法
var userDef = computed[key];
var getter = typeof userDef === 'function' ? userDef : userDef.get;
if (getter == null) {
warn(
("Getter is missing for computed property \"" + key + "\"."),
vm
)