16-Vue数据监视

发布时间 2023-09-21 17:18:44作者: 马铃薯1

我们先探讨一个数据更新时的问题,假设在以下人员列表中,改变"马冬梅"的信息,可以通过什么方法

1)第一种方法(奏效)

数据更新时,方法奏效

this.persons[0].name = "马老师"
this.persons[0].age = 50
this.persons[0].sex = "男"

2)第二种方法(不奏效)

数据更新时,Vue不监听,模板不改变,但通过控制台命令,vm.persons[0].name  发现内部数据已经发生改变

this.persons[0] = {id:"001",name:"马老师",age:50,sex:"男"}

3)第三种方法

 

模拟一个数据监测

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>数据更新时的一个问题</title>
        <!--  引入Vue  -->
        <script type="text/javascript" src="../js/vue.js"></script>
    </head>
    <body>
        <script type="text/javascript">
            // 阻止 vue 在启动时生成生产提示
            Vue.config.productionTip = false

            // 声明一个变量
            let data = {
                name:"马铃薯",
                address:"河北"
            }

            // // 声明一个中间变量
            // let tmp = ""
            // // 定时器方法,每隔一定时间就调用函数,方法或对象
            // setInterval(()=>{
            //     if(data.name !== tmp){
            //         tmp = data.name
            //         console.log("name正在被修改")
            //     }
            // },100)

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

            // Observer 构造函数
            function Observer(obj){
                // 汇总对象中所有属性,形成一个数组
                const keys = Object.keys(obj)
                // 遍历,forEach() 方法对数组的每个元素执行一次提供的函数
                keys.forEach((k)=>{
                    // Object.defineproperty方法的作用就是直接在一个对象上定义一个新属性,或者修改一个已经存在的属性
                    Object.defineProperty(this,k,{
                        get(){
                           return obj[k]
                        },
                        set(val){
                            obj[k] = val
                            console.log(`${k}正在被修改,进行解析模板,生成虚拟DOM...`)
                        }
                    })
                })
            }

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

        </script>
    </body>
</html>