Vue 的响应式原理

数据发生改变,界面跟着更新,如图所示:

<!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">
        {{message}}
        {{message}}
        {{message}}
    </div>
    <script src="../Vue源码/vue-2.6.14/dist/vue.js"></script>
    <script>
        const app = new Vue({
            el:'#app',
            data(){
                return{
                    message:'哈哈哈'
                }
            }
        })
    </script>
</body>
</html>

这就是 vue 的响应式,那么 vue 内部是如何实现的呢?

1.app.message 修改数据,Vue 内部是如何监听 message 数据发生改变的 ?

vue 内部是通过 Object.defineProperty 监听对象属性的改变

2.当数据发生改变时,Vue 是如何通知哪些地方刷新界面的 ?

通过发布订阅者模式来通知哪些页面需要进行刷新

    <script>
        const obj = {// 首先拿到数据对象
            message:'哈哈哈',
            name:'why'
        }
        Object.keys(obj).forEach(key => {// 然后遍历对象,拿到里面的每一个 key 和 值
            let value = obj[key]

            //重新定义 obj,增加了两个方法 set 和 get 
            Object.defineProperty(obj, key, {
                set(newValue){//值发生改变时执行该函数,获取新值
                    console.log('监听' + key +'改变')
                    //哪里使用就通知哪里,如何确定哪里进行了使用呢?-----解析html获取哪里进行了使用(发布订阅者模式)
                    value = newValue

                    dep.notify()// 订阅者发生改变
                },
                get(){//监听对应的值
                    console.log('获取'+ key + '对应的值')

                    return value
                }
            })
        })

        //发布者订阅者模式

        //1.发布者
        class Dep {
            constructor(){// new Dep() 的时候调用 constructor
                this.subs = []
            }
            
            addSub(watcher){//把订阅者添加进来
                this.subs.push(watcher)
            }

            notify(){//用来通知订阅者发生改变
                this.subs.forEach(item =>{
                    item.update()
                })
            }
        }

        //2.订阅者
        class Watcher{
            constructor(name){
                this.name = name
            }
            update(){//在这里更新界面
                console.log(this.name + '发生update')
            }
        }

        const dep = new Dep()

        const w1 = new Watcher('item1')
        dep.addSub(w1)

        const w2 = new Watcher('item2')
        dep.addSub(w2)

        const w3 = new Watcher('item3')
        dep.addSub(w3)
        
    </script>

 

vue 的响应式原理如图:

​​​​​​​

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值