Vue中的数据代理

Object.defineProperty方法

这个方法是给一个对象添加属性用的,是es6的方法。

js 复制代码
<script>
    let person = {
        name:'kunkun',
        sex:'男',
    }
    Object.defineProperty(person,'age',{
        value:'18'
    })
    console.log(person);
</script>

运行打开控制台,可以看到如下结果:

可以发现上面的age属性的颜色比其它属性的颜色更淡,说明该属性是不参与枚举的,也就是不参与遍历。当我们用Object.keys(person)遍历时,不会出现age属性。如下图:

Q:想要该属性加入枚举该怎么做呢?

A:在配置项里加入enumerable属性并将其值设为true即可。

js 复制代码
    Object.defineProperty(person,'age',{
        value:'18',
        enumerable:true,//控制属性是否可以枚举,默认为false
    })

Q:想要该属性能够被修改该怎么做呢?

A:在配置项里加入writable属性并将其值设为true即可。

js 复制代码
    Object.defineProperty(person,'age',{
        value:'18',
        enumerable:true,//控制属性是否可以枚举,默认为false
        writable:true,//控制该属性是否可以被修改,默认为false
    })

Q:想要该属性能够被删除该怎么做呢?

A:在配置项里加入configurable属性并将其值设为true即可。

js 复制代码
    Object.defineProperty(person,'age',{
        value:'18',
        enumerable:true,//控制属性是否可以枚举,默认为false
        writable:true,//控制该属性是否可以被修改,默认为false
        configurable:true,//控制该属性是否可以被删除,默认为false
    })

有这样一个需求,我有一个number变量,然后person对象有一个age属性,且该属性的值是来源于number变量。用Object.defineProperty方法,当number值更改时,age属性自动更改,该怎么做呢?如下代码:

js 复制代码
<script>
    let number = 18
    let person = {
        name:'kunkun',
        sex:'男',
    }
    Object.defineProperty(person,'age',{
        get(){
            console.log('读取到的age属性值为:',number);
            return number
        },
        //当修改person的age属性时,getter函数会被调用,且会收到修改的值        
        set(value){
            console.log('修改了age属性值为:',value);
            number = value
        }
    })
    console.log(person)
</script>

结果如下:

理解数据代理

数据代理:通过一个对象代理对另一个对象中属性的操作(读/写),先上一个简单的例子:

js 复制代码
<script>
    //数据代理:通过一个对象代理对另一个对象中属性的操作(读/写)
    //通过obj2读取到obj的x并且能够修改x的值
    let obj = {x:100}
    let obj2 = {y:200}
    Object.defineProperty(obj2,'x',{
        get(){
            return obj.x
        },
        set(value){
            obj.x= value
        }
    })
</script>

在控制台进行一顿操作后,运行结果如图:

如上图所示我们通过obj2对象修改掉了obj对象中的x属性对应的值。
这就是一个简单的数据代理。

Vue中的数据代理

数据代理如下图图示,这里直接用了尚硅谷讲课的图,相关章节在这里

其实Vue中的_data就近似于我们在写Vue实例时配置的data属性(_data中还有很多属性,是Vue内部用来做数据处理等操作的相关属性),vm用_data来取到我们在data中设置的值,比如vm._data.name的值就和vm.name的值是一模一样的。vm就相当于是一个数据代理。Vue中的数据代理能够更加方便的操作data中的数据。

Vue中数据代理的基本原理:

  1. 通过Object.defineProperty()把data对象中所有的属性添加到vm上。
  2. 为每个添加到vm上的属性指定一个getter和setter函数。
  3. 在getter和setter内部去操作(读/写)data中对应的属性。
相关推荐
三十_A12 分钟前
如何正确实现圆角渐变边框?为什么 border-radius 对 border-image 不生效?
前端·css·css3
小满zs27 分钟前
Next.js第十三章(缓存组件)
前端
前端老宋Running1 小时前
“受控组件”的诅咒:为什么你需要 React Hook Form + Zod 来拯救你的键盘?
前端·javascript·react.js
风止何安啊1 小时前
拿捏 React 组件通讯:从父子到跨组件的「传功秘籍」
前端·react.js·面试
懒得不想起名字1 小时前
将flutter打成aar包嵌入到安卓
前端
Highcharts.js1 小时前
官方文档|Angular 框架集成 Highcharts Dashboards
前端·javascript·angular.js·highcharts·看板·使用文档·dashboards
韭菜炒大葱1 小时前
React 新手村通关指南:状态、组件与魔法 UI 🧙‍♂️
前端·javascript·react.js
Dwzun2 小时前
基于SpringBoot+Vue的二手书籍交易平台系统【附源码+文档+部署视频+讲解)
java·vue.js·spring boot·后端·spring·计算机毕业设计
天天扭码2 小时前
深入MCP本质——编写自定义MCP Server并通过Cursor调用
前端·mcp
北辰alk2 小时前
Vue3 事件修饰符深度解析:从基础到高级应用的完整指南
vue.js