原理

034_Vue监测数据的原理_对象 - 图1

vm 始终可以将 data 对象的数据 加工到 vm._data ,无论data对象中的元素有多少子对象

测试用例,运行可以在浏览器的控制台查看:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />
        <title>Vue监测数据改变的原理</title>
        <!-- 引入Vue -->
        <script type="text/javascript" src="../js/vue.js"></script>
    </head>
    <body>
        <!-- 准备好一个容器-->
        <div id="root">
            <h2>学校名称:{{name}}</h2>
            <h2>学校地址:{{address}}</h2>
        </div>
    </body>

    <script type="text/javascript">
        Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。

        const vm = new Vue({
            el:'#root',
            data:{
                name:'尚硅谷',
                address:'北京',
                student:{
                    name:'tom',
                    age:{
                        rAge:40,
                        sAge:29,
                    },
                    friends:[
                        {name:'jerry',age:35}
                    ]
                }
            }
        })
    </script>
</html>

模拟一个数据监测

源码:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />
        <title>Document</title>
    </head>
    <body>
        <script type="text/javascript" >

            let data = {
                name:'尚硅谷',
                address:'北京',
            }

            //创建一个 监视的 实例对象,用于监视 data中属性 的变化
            const obs = new Observer(data)        
            console.log(obs)    

            //准备一个vm实例对象
            let vm = {}
            vm._data = data = obs

            //写一个监视函数:
            function Observer(obj){
                //汇总 对象中所有的属性 形成一个 数组
                const keys = Object.keys(obj)
                //遍历 keys 数组中的 每个元素k
                keys.forEach((k)=>{
                    //this - 是 Observer() 的实例对象
                    //
                    Object.defineProperty(this,k,{
                        get(){
                            //把传入的对象身上k对应的值传出去。
                            return obj[k]
                        },

                        set(val){
                            //$(k) 模板字符串
                            console.log(`${k}被改了,我要去解析模板,生成虚拟DOM.....我要开始忙了\n`)
                            //把传入的对象身上k对应的值修改为 val
                            obj[k] = val
                        }
                    })
                })
            }
        </script>
    </body>
</html>