浅浅分析Vue中监视数据的原理?Vue是如何实现对数据的监视?

前言

这篇文章主要为了分析Vue监视数据的原理,希望自己理清思路,也希望对还在学习Vue的小伙伴有所帮助。

一、Vue监视数据的原理

底层逻辑:Vue通过Object.defineproperty()方法中的get()函数实现对数据的读取,通过set()函数实现对数据的监控

特点:Vue会监视data中所有的层级的数据


二、如何监视对象中的数据

通过set()函数实现监视

特点:要监视的数据一定要在data中写入,即在new Vue时就要想好data中的第一层数据
大致底层原理代码:

    <script>
        //准备一组数据对象
        let data = {
            star: '周杰伦',
            sex: '男',
        };

        //利用Observe构造函数观察数据
        function Observe(obj) {
            //用方法Object.keys()得到数据对象的属性名,并将属性名汇总为一个数组
            const keys = Object.keys(obj);
            
            //遍历属性名数组
            keys.forEach((k) => {
                //利用Object.definePropert方法实现对数据的I监视和修改
                Object.defineProperty(this, k, {
                    get() {
                        return obj[k]
                    },
                    set(val) {
                        obj[k] = val
                    }
                })
            })
        }

        new Observe(data)
    </script>

1.后期追加属性有何影响

后期为对象追加的属性(既不能直接在_data或data上添加属性),Vue默认不做响应式处理(后期追加的属性,Vue没有为其添加getter和setter)

2.如何后期为对象追加属性

如果需要后期为对象追加属性,那么Vue提供如下API可以实现追加属性的数据响应式

Vue.set(target,propertyName/index,value) ​
vm.$set(target,propertyName/index,value)


三、如何监视数组中的数据

通过包裹数组更新元素的方法实现监视

特点:数组中的对象没有getter和setter,但数组中对象中的属性有getter和setter

通过包裹数组更新元素的方法实现数据监视,本质就是做了两件事:

(1). 调用原生对应的方法对数组进行更新。

(2). 重新解析模板,进而更新页面。

Vue中修改数组中数据的方法

​(1). 使用这些API:push()pop()shift()unshift()splice()sort()reverse()
(2). Vue.set() vm.$set()

总结

文章可能写的有点乱,会不定期更改

来一个小案例汇总以上知识点,案例中都有解释,练习案例应该会更明白一下

<body>
    <div id="app">
        <h2>宠物信息</h2>
        <button @click="cat.age ++">年龄+1</button><br/><br/>
        <button @click="addSex">添加性别属性,默认值为:男</button><br/><br/>
        <button @click="addFriend">在列表首位添加一个朋友</button><br/><br/>
        <button @click="changeFriend">修改第一个朋友的名字为大黄</button><br/><br/>
        <button @click="addHobby">添加一个爱好</button><br/><br/>
        <button @click="changeHobby">修改第一个爱好为开车</button>
        <h3>姓名:{{cat.name}}</h3>
        <h3>年龄:{{cat.age}}岁</h3>
        <h3 v-show="cat.sex">性别:{{cat.sex}}</h3>
        <h3>爱好</h3>
        <ul>
            <li v-for="(h,index) in hobbys" :key="index">{{h}}</li>
        </ul>
        <h3>朋友</h3>
        <ol>
            <li v-for="(f,index) in friends">{{f.name}} - {{f.age}} - {{f.sex}}</li>
        </ol>
    </div>
    <script>
        const vm = new Vue({
            el: "#app",
            data: {
                cat: {
                    name: "憨瓜",
                    age: 3,
                },
                hobbys: ['猫条', '吸薄荷', '咬人'],
                friends: [{
                    name: "波妞",
                    age: '2岁',
                    sex: '母'
                }, {
                    name: "妲己",
                    age: '2岁',
                    sex: '女'
                }]
            },
            methods: {
                //添加性别属性
                addSex() {
                    // this.cat.sex = "男"; //这种方法为对象添加属性,Vue没办法做响应式
                    //Vue修改对象类型的数据可以通过Vue.set方法和vm.$set方法实现
                    Vue.set(this.cat, 'sex', '男')
                },
                //添加朋友
                addFriend() {
                    //Vue中修改数组类型的数据可以直接用原生修改数组的方法,有push,pop,unshift,shift,splice,sort,reverse
                    this.friends.unshift({
                        name: '小白',
                        age: '3岁',
                        sex: '女'
                    })
                },
                //修改第一个朋友的名字
                changeFriend() {
                    //第1种方法:通过对象的方法改变数据
                    // this.friends[0].name = "大黄";
                    //第2种方法:通过数据的方法修改数据
                    this.friends.splice(0, 1, {
                        name: "大黄",
                        age: '3岁',
                        sex: '女'
                    })

                },
                //添加一个爱好
                addHobby() {
                    //Vue中修改数组类型的数据可以直接用原生方法
                    this.hobbys.push('跑酷')
                },
                //修改第一个爱好
                changeHobby() {
                    this.hobbys.splice(0, 1, '猫粮')
                }
            },

        })
    </script>
</body>

运行结果

网页运行图

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值