使用原生JS实现一个V-model的效果

需求: 使用原生js实现一个v-model的效果

前言: vue中的 v-model是 :value + @input 方法

         vue响应式的核心 Object.defineProperty这个方法

思路: Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有           的属性,并返回此对象。

        Object.defineProperty 方法 对 data中定义的数据做劫持, 劫持出一个新对象,我们在操作数据的时候其实一直操作的是这个新对象

        Object.defineProperty有三个参数:

        参数一: 我们要处理的对象

        参数二: 这个对象上的属性

        参数三: 一个配置对象 其中有get 和 set 方法

            get方法实时将我们原有对象的最新状态同步给新对象

            set方法当值修改后会触发, 这个方法中可以接收一个参数value=>最新的值, 将这个值同步给我们原有的对象

            修改视图的时候, 把值赋给我们新对象对应的属性,触发set方法, 实现数据双向绑定

以下代码:

<h2></h2>
<input></input>
 // 获取dom元素
    const h2 = document.querySelector('h2')
    const ipt = document.querySelector('input')
    const obj = {name: 'lisi'} 
    let _data = {} // vue中模拟我们真实data中的数据 做了一份新的拷贝
    // Object.defineProperty() 他的三个参数
    // 参数一: 我们要处理的对象 
    // 参数二: 这个对象上边的属性 
    // 参数三: 配置对象
    Object.defineProperty(_data, 'name', {
      get() {
        return obj.name // 虚拟数据中实时同步我们原有的数据
      },
      set(val) {
        console.log('属性修改了', val) // 李四
        obj.name = val // 只要obj.name发生更改 _data中的name属性也会同步
        // 将最新的数据同步给视图
        h2.innerHTML = val
        ipt.value = val
      }
    })
    console.log(obj)
    _data.name = '李四'
    console.log(obj)
    // 给两个dom元素设置默认内容
    h2.innerText = _data.name
    ipt.value = _data.name
    // 双向绑定 数据驱动视图 视图驱动数据
    // 监听input的input事件
    ipt.addEventListener('input', (e) => {
      console.log(e.target.value)
      _data.name = e.target.value
    })

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值