defineProperty
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<div id="app">
{{ fullName }}
</div>
<script src="<https://cdn.bootcdn.net/ajax/libs/vue/2.6.14/vue.js>"></script>
<script>
const vm = new Vue({
el: '#app',
data: {
firstName: 'John',
lastName: 'Doe',
},
computed: {
// fullName() { // defineProperty 中的 get 方法
// return this.firstName + ' ' + this.lastName;
// },
fullName: {
get() {
return this.firstName + ' ' + this.lastName;
},
set(val) {
console.log(val)
}
}
}
});
</script>
</body>
</html>
计算属性:依赖的值发生变化才会重新执行用户的方法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<div id="app">
<!--两次获取,只计算一次-->
{{ fullName }} {{ fullName }}
</div>
<!--<script src="vue.js"></script>-->
<script src="<https://cdn.bootcdn.net/ajax/libs/vue/2.6.14/vue.js>"></script>
<script>
const vm = new Vue({
el: '#app',
data: {
firstName: 'John',
lastName: 'Doe',
},
computed: {
// fullName() { // defineProperty 中的 get 方法
// return this.firstName + ' ' + this.lastName;
// },
fullName: {
get() {
// 读取两次,计算一次 => 缓存机制
console.log('fullName computed');
return this.firstName + ' ' + this.lastName;
},
set(val) {
console.log(val)
}
}
}
});
</script>
</body>
</html>
怎么知道这个值有没有变化呢:计算属性中维护了一个 dirty
属性,表明当前计算属性是不是“脏的”
watcher
, 默认渲染会创造一个渲染 watcher
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<div id="app">
<!--两次获取,只计算一次-->
{{ fullName }} {{ fullName }}
</div>
<!--<script src="vue.js"></script>-->
<script src="<https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.14/vue.min.js>" integrity="sha512-XdUZ5nrNkVySQBnnM5vzDqHai823Spoq1W3pJoQwomQja+o4Nw0Ew1ppxo5bhF2vMug6sfibhKWcNJsG8Vj9tg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script>
const vm = new Vue({
el: '#app',
data: {
firstName: 'John',
lastName: 'Doe',
},
// 计算属性:依赖的值发生变化才会重新执行用户的方法
computed: {
// fullName() { // defineProperty 中的 get 方法
// return this.firstName + ' ' + this.lastName;
// },
fullName: {
get() {
// 读取两次,计算一次 => 缓存机制
console.log('fullName computed');
return this.firstName + ' ' + this.lastName;
},
set(val) {
console.log(val)
}
}
}
});
// 依赖变化,重新计算
setTimeout(() => {
vm.firstName = 'Larry';
}, 1000);
</script>
</body>
</html>
firstname
和 lastname
都有各自的 dep
, 都需要收集 计算属性 fullname
这个 watcher
firstname
和 lastname
发生变化时需要更新计算 watcher
的 dirty
dep
除了记住计算属性 watcher
外还需要记住外一层的 渲染 watcher
, 通知更新视图, 所以这里有个嵌套关系渲染 watcher
,然后产生 计算属性 watcher
watchers