vue响应式原理解析

vue响应式原理解析

1、什么是响应式

当修改data中的某一属性值时,调用该属性的界面视图也随着发生改变!

2、灵魂拷问

2.1 vue内部是如何监听数据的改变

答:使用Object.defineProperty监听对象属性的改变

2.2 当数据发生改变,vue是如何知道要通知哪些页面的?

答:使用发布者订阅者模式

3、代码解析

  • 定义一个data对象,并获取它所有的属性与属性值
<script>
	 const data = {
        message: "哈哈哈",
        name: "lala"
     } 
     
	// 获取data对象的所有属性与属性值
	Object.keys(data).forEach(key=> {
		let value = data[key]
	})
</script>
  • 使用Object.defineProperty()方法,侦测数据的变化(劫持用户对对象属性的取值和赋值)
<script>
	 const data = {
        message: "哈哈哈",
        name: "lala"
     } 
     
	// 获取data对象的所有属性与属性值
	Object.keys(data).forEach(key=> {
		// 根据属性获取对应的属性值
		let value = data[key];
		
		Object.defineProperty(data, key, {
			// 监听任意属性的改变
            set(newValue) {
                console.log('监听' + key+ '的改变');
                value = newValue
            },
            // 获取任意属性的对应值
            get() {
                console.log('获取' + key+ '对应的值');
                return value;
            }
        })
	})
</script>
  • 监听到某一属性(如:message)的改变后要如何?
    答:告诉调用message的所有界面,数据发生改变了!
    问:那又如何知道哪些界面调用message了呢?
    答:根据解析html代码呀,看看那些页面在调用message。
    路人甲:说白了,就是让界面订阅数据,一但某一数据发生改变,就要通知调用这一数据的界面,让他们更新数据!

  • 发布者订阅者模式

    • 发布者
<script>
	/*
	* dependence:依赖 ===== 简写dep
	* subscribe:订阅者 ===== 简写subs
	*/
	class Dep {
        constructor() {
            this.subs = []    // 该数组存储所有订阅者(对某一属性有依赖的东西)
        }
        // 添加订阅者
        addSub(sub) {
            this.subs.push(sub)
        }
        // 通知所有订阅者更新视图
        notify() {
            // 获取所有订阅者,并让每一个订阅者更新数据
            this.subs.forEach( item => {
                item.updated()
            })
        }
    }
</script>
用 addSub 方法可以在目前的 Dep 对象中增加一个 sub 的订阅操作;
用 notify 方法通知目前 Dep 对象的 subs 中的所有 sub 对象触发更新操作。
所以当需要添加订阅者的时候调用 addSub,当需要派发更新的时候调用 notify。
<script>
	let dep = new Dep()
	dep.addSub()
    dep.notify()
</script>
  • 订阅者
<script>
	class watcher {
        constructor(name) {
            this.name = name
        }
        // 更新数据
        updated() {
            console.log(this.name + '发生改变!!!');
        }
    }
</script>
每产生一个订阅者,将他添加进subs 中,并在数据发生变化时通知更改数据!
<script>
	let w1 = new watcher('界面a')
    dep.addSub(w1)
    dep.notify()
</script>

4、看图理解

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值