【Vue知识点】——Vue2和Vue3的数据劫持

本文深入探讨了Vue中数据劫持的概念,分析了Vue2中Object.defineProperty如何实现数据绑定,包括其局限性,以及Vue3中如何通过Proxy改进这些问题,强调了Proxy在性能和功能上的优势。

数据劫持

   上一次面试中,考官有问我对Vue当中双向绑定(v-model)的理解,我当时回答的好像很片面,只是解释了这个内置指令的含义,当时面试官听完我的回答,也并没有对我的回答做出任何反应。我就明白了这应该是我的回答可能是错的或者理解的不够深刻。于是我一有空,就对Vue当中的双向绑定进行了更深刻的钻研。

v-model理解

  • v-model是Vue的内置指令,本质上是一种语法糖。主要是负责监听用户的输入事件来更新数据
  • v-model指令可以在表单 input、textarea以及select元素上创建双向数据绑定它会根据控件类型自动选取正确的方法来更新元素。
  • v-model本质上还是单向数据流,通过v-bind绑定value值,此时只能通过在data中修改输入框的显示值,即数据只能从data中流向视图,而不能获取用户输入的数据从而修改data中的值;此时需要绑定一个@input事件来实现获取用户输入的数据从而修改data中的值。从而实现数据的双向绑定:数据向下,事件向上

v-model其实是简化了两个操作:
   1.v-bind绑定value属性的值;

   2.v-on绑定input事件监听到函数中,函数会获取最新的值赋值到绑定的属性中;

<input type="text" v-model="textDetail">
<!--等价于-->    
<input type="text" :value="textDetail" @input="textDetail=$event.target.value">

   此时我对data中定义的textDetail挺好奇的:该属性是如何绑定到页面中的?该属性是如何进行一次次修改的?我通过打印输出该数据得到:
   大概意思是在获取data数据至页面应该是调用了get方法,修改该属性应该是调用了set方法。那么问题来了!!!
data中的数据

为什么在data中定义的数据会自动携带get、set属性方法呢?

  • 其实此刻正文才刚刚开始
    哈哈哈

数据劫持

数据劫持,其实就是数据代理
指的是在访问或者修改对象的某个属性时,通过一段代码拦截这个行为,进行额外的操作或者修改返回结果。

data与_data

我们通过全局输出this可以得到:
全局this
将data展开得到:
_data
   _data中的数据与data中的数据一致,只不过多了对数据的get和set方法还有一个Observer对象,Vue就是通过_data来实现对data的数据劫持,通过调用_data中的get和set方法去修改和展现数据。

__ob__: Observer对象是vue这个框架对数据设置的监控器,监控数据的变化,一般都是不可枚举的。

原来是_data上的数据携带get和set方法,那问题还是没解决,_data上存在get和set方法是怎么来的?

Object.DefineProperty

   Vue2中是通过Object.DefineProperty实现数据劫持,作用是往data中的一个对象中添加属性,get()和set()方法就是通过Object.DefineProperty添加的,从而实现当外部想要修改data中的值。

Object.DefineProperty使用规范为

  • Object.defineProperty(对象,要添加得键,{配置对象})

配置对象的主要属性有:

  • value:20 //添加的属性的value
  • enumerable:true //是否可以被枚举获取到 默认:false
  • writeable:true //value是否可以被修改 默认:false
  • configurable:true //是否可以被删除 默认:false
  • get(){} //当这个属性被获取的时候调用
  • set(){} //当这个属性被修改的时候调用

Object.DefineProperty的实际应用

const user={
   
   
            name:"jack",
        }
        var name=user.name;
        Object.defineProperty(user, "name", {
   
   
            enumerable: true,
            writeable: true,
            configurable: true,

            get() {
   
    
                return name
             }, 
            set(e) {
   
    
                name=e
             } 
        })

可以在浏览器控制台中输出name以及修改name:
控制台
Object.DefineProperty就是这样把data中的数据全部加工了一遍,添加上了get和set方法,从而实现了数据的劫持。

Object.DefineProperty的缺点

1.**对象上定义新属性时,Object.defineProperty监听不到。**因为Object.DefineProperty只能对对象的单个属性劫持,如果要对对象进行劫持,需要遍历。

		const user = {
   
   
            name: "jack",
        }
        var name = user.name;
        Object.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值