<div id="app">
{{message}}
{{message}}
{{message}}
</div>
<script src="js/vue.js"></script>
<script>
const app = new Vue({
el:'#app',
data: {
message: 'O(∩_∩)O哈哈~'
}
})
</script>
我们app.message修改message信息:
页面上message内容改为:
1.app.message修改数据,Vue内部是如何监听message数据的变化?
Object.defineProperty->监听对象属性的改变
将data对象传入Vue里
<script>
const obj = {
message: 'O(∩_∩)O哈哈~',
name: 'smy'
}
//1.取出obj中所有的key进行遍历
Object.keys(obj).forEach(key =>{
//拿到遍历的值
let value = obj[key]
拿到值后,接下来我们监听值的改变
原来的message和name不好监听,所以我们把他们原来的属性全部重新定义一下,这里就用到了Object.defineProperty
Object.defineProperty(obj, key, {
set(newValue) {
console.log('监听' + key + '改变');
value = newValue
},
get() {
console.log('获取' + key + '对应的值');
return value
}
})
})
obj.name = 'yyqx'
</script>
(上面是一个完整的代码,方便解释每段代码,我才分开写的)
如果我们obj.name = 'yyqx'
修改name的值,我们要告诉谁我们把这个值修改了呢?
- 谁用告诉谁,谁在用了
- 张三李四王五都在用,我们怎么知道谁在用?
- 那么我们就需要对div中的内容做解析,
- 根据解析HTML代码,获取到哪些人有用属性,而且这些人在用message的时候会用到message的属性get,
- 谁用一次,谁就会调用一次Object.defineProperty下面这个get
- get()中:张三get,李四get,王五get
- 一旦上面newValue发生改变我们就通知一下这三个人,也就是发布订阅者模式,让这三个人订阅newValue的改变
<body>
<div id="app">
{{message}}<!--张三用了-->
{{message}}<!--李四用了-->
{{message}}<!--王五用了-->
{{name}}
</div>
<script src="js/vue.js"></script>
<script>
const obj = {
message: 'O(∩_∩)O哈哈~',
name: 'smy'
}
Object.keys(obj).forEach(key =>{
let value = obj[key]
Object.defineProperty(obj, key, {
set(newValue) {
console.log('监听' + key + '改变');
value = newValue
},
get() {
console.log('获取' + key + '对应的值');
return value
}
})
})
2.当数据发生改变,Vue如何知道通知哪些人,界面发生刷新?
发布订阅者模式
当通知到这三个人数据变化了,他们还要自己update一下更新界面,也就出现了在Watcher类中update一下,我们把修改好的name加入到Dep中去之后dep.notify()通知订阅者,在Dep发布者中遍历通知订阅者更新界面
//发布者, Dep用来存储所有对属性有依赖的东西
class Dep {
constructor() {
//数组中记录谁要订阅我这个属性
this.subs = []//subscribe
}
//添加watch对象,一旦调用的函数加进来,就把watcher加进来
//也就进行下面的const w1 = new Watcher('张三'); dep.addSub(w1)操作
addSub(watcher) {
this.subs.push(watcher)
}
//通知
notify() {
this.subs.forEach(item => {
item.update()
})
}
}
//监听观察(订阅者)
class Watcher {
constructor(name) {
this.name = name;
}
update() {
console.log(this.name + '发生update');
}
}
const dep = new Dep()
const w1 = new Watcher('张三')//张三用了一次,这个就在get中
dep.addSub(w1)//把这个w1加入到dep中去
dep.notify()//通知订阅者
</script>
(上面是一个完整的代码,方便解释每段代码,我才分开写的)
过程图解:
将上面的案例套入这个过程图解中
(资料参考来源微博’coderwhy‘,感谢王红元老师💪)