zoukankan      html  css  js  c++  java
  • vue.$set实现原理

    上源码:

    export function set (target: Array<any> | Object, key: any, val: any): any {
      if (process.env.NODE_ENV !== 'production' &&
        (isUndef(target) || isPrimitive(target))
      ) {
        warn(`Cannot set reactive property on undefined, null, or primitive value: ${(target: any)}`)
      }
      // 判断目标值是否为数组,并且key值是否为有效的数组索引
    if (Array.isArray(target) && isValidArrayIndex(key)) {
      // 对比数组的key值和数组长度,取较大值设置为数组的长度 target.length
    = Math.max(target.length, key)
      // 替换目标值 target.splice(key,
    1, val) return val }
      // 如果目标值是对象,并且key值是目标值存在的有效key值,并且不是原型上的key值
    if (key in target && !(key in Object.prototype)) {
      // 直接更改目标值 target[key]
    = val return val } const ob = (target: any).__ob__ // 判断目标值是否为响应式的 if (target._isVue || (ob && ob.vmCount)) { // 如果是vue根实例,就警告 process.env.NODE_ENV !== 'production' && warn( 'Avoid adding reactive properties to a Vue instance or its root $data ' + 'at runtime - declare it upfront in the data option.' ) return val } if (!ob) { // 如果目标值不是响应式的,那么值需要给对应的key赋值 target[key] = val return val }
      // 其他情况,目标值是响应式的,就通过Object.defineProperty进行数据监听 defineReactive(ob.value, key, val)
      // 通知更新dom操作 ob.dep.notify()
    return val }

    大概流程就是:

      1.判断目标值是否为有效值,不是有效值直接停止

      2.判断是否为数组,并且key值是否为有效的key值

        如果是数组,就选择数组的长度和key值取较大值作为数组的新的length值,并且替换目标值

        splice方法,重写了,所以执行splice,会双向数据绑定

      3.判断目标值是否为响应式的__ob__

        如果是vue实例,直接不行

        如果不是响应式的数据,就是普通的修改对象操作

        如果是响应式数据,那就通过Object.defineProperty进行数据劫持

      4.通知dom更新

  • 相关阅读:
    升级到virtualbox2.1.4
    gentool 工具 modulerebuild
    解决man乱码问题
    关于HyperV的Linux驱动
    使用tmpfs优化firefox
    使用gmbox下载google歌曲
    升级到xorgserver1.5时出现的问题
    windows下使用where命令
    CSS中一些渐变效果与透明
    asp.net下密码框的一些小问题
  • 原文地址:https://www.cnblogs.com/yaxinwang/p/13827529.html
Copyright © 2011-2022 走看看