vue——MVVM、Object.defineProperty()、数据代理

本文详细解析了MVVM模式,重点探讨了Vue框架中的数据绑定原理。通过实例展示了数据双向绑定如何通过Object.defineProperty()实现,以及数据代理如何使操作data中的属性变得更便捷。同时,文中通过代码示例解释了数据代理的基本原理和好处。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

MVVM

1.M:模型(Model):对应data中的数据

2.V:视图(View):模板代码(对应DOM)

3.VM:视图模型(ViewModel):Vue的实例对象

结论:

​ 1.data中所有的属性最后都出现在了实例对象上

​ 2.vm上所有的属性及vue原型上所有属性,在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>
    <script src="../js/vue.js"></script>

</head>

<body>
    <!-- 视图:View -->
    <div id="root">
        <p>姓名:{{name}}</p>
        <p>年龄:{{age}}</p>
        <!-- 可以写vm上面的所有属性和方法,也可以写它原型上的属性和方法 -->
        <!-- 可以直接调用vm实例上的属性 -->
        <p>插值表达式里面可以存放的东西:{{$options}}</p>
    </div>
    <script>
        Vue.config.productionTip = false;
        // 视图模型:ViewModel
        const vm = new Vue({
            el: "#root",
            // 模型:Model
            data() {
                return {
                    name: "张三",
                    age: 28
                }
            }
        });
        // 在data里面定义的属性,也变成了vue实例对象vm的属性
        console.log(vm);
    </script>
</body>

</html>
数据双向绑定的原理:Object.defineProperty()
<!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>
    <script>
        let num = 28;
        let person = {
            name: "张三",
            sex: "男",
            // 在这里添加的age属性可以遍历出来
            // age: 28
        };
        // 通过 Object.defineProperty()添加的属性不可以枚举,就是不参加遍历,而且后面也不可以改变其属性
        // defineProperty有三个参数,第一个参数是给哪个对象加,第三个属性是加的什么属性,第三个参数是属性的配置项
        // 这里的age属性可以遍历出来
        // ,不可以枚举
        Object.defineProperty(person, 'age', {
            /* value: 18,
            enumerable: true, //enumerable控制属性是否可以枚举,默认是false
            writable: true, //控制属性是否可以被修改,默认值是false
            configurable: true, //控制属性是否可以被删除,默认值是false */
            // 当读取到person的age属性时,get函数(getter)就会被调用,且返回值就是age的值
            // age的值随num改变
            get() {
                console.log("age被读取了");
                return num
            },
            // 当修改person的age属性时,set函数(setter)就会被调用且会收到修改后的值,参数value就是修改后的值
            set(value) {
                console.log("age被修改了:" + value);
                // 若是没有下面的这句代码,age值虽然修改了,但是person中的age值还是没有变,因为num没有变。所以将修改后的新值赋给num,
                num = value
            }
        });
        // Object.keys(对象)可以将作为参数的对象的属性名提取出来,组成一个数组
        console.log(Object.keys(person));
        // 这个for in也可以遍历对象也可以遍历数组,输出属性名
        // foreach是遍历对象
        /* for (const key in person) {
            console.log(key);
        } */
        console.log(person);
    </script>
</body>

</html>
数据代理:通过一个对象代理对另一个对象中属性的操作(读/写)

1.vue中的数据代理:通过vm对象来代理data对象中属性的操作(读/写)

2.vue中数据代理的好处:更加方便的操作data中的数据

3.基本原理:通过Object.defineProperty()把data对象中所有属性添加到vm上,为每一个添加到vm上的属性,都指定一个getter**/setter。在getter/**setter内部去操作(读/写)data中对应的属性

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BHSR5qQH-1629187649410)(C:\Users\ltting\AppData\Roaming\Typora\typora-user-images\image-20210817155829466.png)]

<script>
        let obj1 = {
            x: 100
        };
        let obj2 = {
            y: 200
        };
        // 给obj2添加一个x属性,属性值是obj1的x属性的属性值;而obj2的x属性值发生改变时,obj1的x属性值也跟着改变
        Object.defineProperty(obj2, 'x', {
            get() {
                return obj1.x
            },
            set(value) {
                obj1.x = value
            }
        })
    </script>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值