美文网首页vue
vue 数据响应式原理

vue 数据响应式原理

作者: 浅忆_0810 | 来源:发表于2021-07-07 22:33 被阅读0次

    1. Vue 2.x

    // 模拟 Vue 中的 data 选项
    let data = {
      msg: 'hello'
    }
    
    // 模拟 Vue 的实例
    let vm = {}
    
    // 数据劫持:当访问或者设置 vm 中的成员的时候,做一些干预操作
    Object.defineProperty(vm, 'msg', {
      // 可枚举(可遍历)
      enumerable: true,
      // 可配置(可以使用 delete 删除,可以通过 defineProperty 重新定义)
      configurable: true,
      // 当获取值的时候执行
      get () {
        console.log('get: ', data.msg)
        return data.msg
      },
      // 当设置值的时候执行
      set (newValue) {
        console.log('set: ', newValue)
        if (newValue === data.msg) {
          return
        }
        data.msg = newValue
        // 数据更改,更新 DOM 的值
        document.querySelector('#app').textContent = data.msg
      }
    })
    
    // 测试
    vm.msg = 'Hello World'
    console.log(vm.msg)
    

    1.1 如果一个对象中多个属性需要转换 getter/setter 如何处理?

    function proxyData(data) {
      // 遍历 data 对象的所有属性
      Object.keys(data).forEach(key => {
        // 把 data 中的属性,转换成 vm 的 setter/setter
        Object.defineProperty(vm, key, {
          enumerable: true,
          configurable: true,
          get () {
            console.log('get: ', key, data[key])
            return data[key]
          },
          set (newValue) {
            console.log('set: ', key, newValue)
            if (newValue === data[key]) {
              return
            }
            data[key] = newValue
            // 数据更改,更新 DOM 的值
            document.querySelector('#app').textContent = data[key]
          }
        })
      })
    }
    

    2. Vue 3.x

    • MDN - Proxy

    • 直接监听对象,而非属性。

    • ES 6中新增,IE 不支持,性能由浏览器优化

    // 模拟 Vue 中的 data 选项
    let data = {
      msg: 'hello',
      count: 0
    }
    
    // 模拟 Vue 实例
    let vm = new Proxy(data, {
      // 执行代理行为的函数
      // 当访问 vm 的成员会执行
      get (target, key) {
        console.log('get, key: ', key, target[key])
        return target[key]
      },
      // 当设置 vm 的成员会执行
      set (target, key, newValue) {
        console.log('set, key: ', key, newValue)
        if (target[key] === newValue) {
          return
        }
        target[key] = newValue
        document.querySelector('#app').textContent = target[key]
      }
    })
    
    // 测试
    vm.msg = 'Hello World'
    console.log(vm.msg)
    

    相关文章

      网友评论

        本文标题:vue 数据响应式原理

        本文链接:https://www.haomeiwen.com/subject/zylwultx.html