likes
comments
collection
share

Object.defineProperty方法(Vue 数据双向绑定原理)

作者站长头像
站长
· 阅读数 12

引言

在学习了Vue的基本使用之后,对于vue框架中的双向数据绑定的实现原理还没了解过,今天看到Object.defineProperty方法后,了解到这个方法涉及到双向数据绑定原理。于是深入了解了一下,特来记录一下。

Object.defineProperty(obj, propertyName, descriptor)

  • objpropertyName

obj是应用描述符的对象,property是obj对象属性

  • descriptor

descriptor可以是属性描述符对象,也可以是访问器描述符对象,这里只说访问器描述符,我们先看一下对象的访问器属性,它们本质上是用于获取和设置值的函数。访问器属性由‘getter’ 和 ‘setter’方法表示,在对象字面量中,用 get 和 set 表示。

let obj = {

    // 当读取obj的name属性时,该方法起作用
    get name(){
        
    }   
    // obj.name = value 当设置obj的name属性值时,该方法起作用
    set name(value) {
         
    }
}

当我们调用 obj.name 时,实际是getter在运行

访问器描述符

在访问器描述符对象中,也有get和set方法,通过这两个方法设置对象的属性

let person = {
  lastName: 'john',
  firstName: 'smith'
}

Object.defineProperty(person, 'fullName', {
  get() {
    return `${this.lastName} ${this.firstName}`
  },
  set(value) {
    [this.lastName, this.firstName] = value.split(' ')
  }
})

person.fullName = 'li yiyi'   // 此时调用的是 set方法,'li yiyi'作为参数
console.log(person.fullName);   // 此时调用的是 get方法,打印的是 'li yiyi'

所以Object.defineProperty()可以很方便地改变对象的属性值,无论是读取对象的属性值还是设置对象的属性值,都会默认去调用它的get和set方法,利用这一点就可以去思考vue中数据双向绑定了。

数据双向绑定

我们先创建一个页面,通过input输入框输入值,同时让下面的div显示input输入内容

Object.defineProperty方法(Vue 数据双向绑定原理)

思路

  • 获取input和div的dom元素
  • 给input元素添加监听器,触发input时间就将输入值存到数据中
  • 在将input输入值存到数据的同时,需要将数据显示到div中
<!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>
  <style>
    #container {
      width: 300px;
      height: 500px;
      background-color: pink;
    }

    #textOutput {
      width: 300px;
      height: 300px;
      background-color: skyblue;
      margin-top: 50px;
    }
  </style>
</head>

<body>
  <div id="container">
    <input type="text" id="textInput">
    <div id="textOutput"></div>
  </div>

  <script>

    let data = {}
    // 先获取dom元素
    let input = document.getElementById('textInput')
    let output = document.getElementById('textOutput')

    // 给 input 元素添加监听输入监听事件
    input.addEventListener('input', function (e) {
      data.value = e.target.value
    })

    Object.defineProperty(data, 'value', {
    // 设置对象属性同时,需要将数据显示到div中
      set(val) {
        output.innerHTML = val
      }
    })
  </script>

</body>

</html>

转载自:https://juejin.cn/post/7148439778805956638
评论
请登录