vue响应式原理

116 阅读1分钟

Obejct.defineProperty()

Vue在获得data时,会将里面的数据通过ES5新增的Object.defineProperty()进行重构,所以Vue不支持IE8及以下更低版本

示例一代码

<script type="text/javascript">

  // 第一种定义对象的方式
  var obj1 = {
    msg: 1,
    name: 2
  }

  // 第二种定义对象的方式
  var obj2 = {}
  Object.defineProperty(obj2, 'msg', {
    get: function() {
      return value
    },
    set: function(arg) {
      value = arg
    }
  })

  Object.defineProperty(obj2, 'name', {
    get: function() {
      console.log('触发了getter')
      return value
    },
    set: function(arg) {
      value = arg
      console.log('触发了setter')
    }
  })
 
  obj2.name = 2
  
  obj2.name
  console.log(obj2)
  console.log(obj2.name)
</script>

示例二代码

<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>

  <div id='app'>
    <input type="text" id='input'><h1 id='msg'></h1>
  </div>
  <script>
    var app = {}
    // 把普通对象的定义,转化成setter/getter方式进行对象定义
    Object.defineProperty(app, 'msg', {
      get: function() {
        return value
      },
      set: function(arg) {
        value = arg
        // 在setter操作里面,通知监听器,更新页面
        watch(value)
      }
    })
    // 当页面数据发生变化时,更新对象,触发setter操作
    document.getElementById('input').addEventListener('keyup', function(e){
      app.msg = e.target.value
    })
    // 监听器
    function watch(value) {
      document.getElementById('msg').innerHTML = value
    }
  </script>

</body>
</html>