zoukankan      html  css  js  c++  java
  • Vue2源码解读(3)

    Vue2源码解读 - $set()使用及实现原理

    • 当我们给响应式的对象新增属性时,新增的属性并不会渲染到页面中
    • 对于响应式的数组,增加元素、修改数组长度时,数组的这些变化也不会反映到页面中

    那么如何让新增的对象或数组实现响应式及时渲染页面呢?

    使用this.$set()

    官方定义

    Vue 不允许在已经创建的实例上动态添加新的根级响应式属性 (root-level reactive property)。然而它可以使用 Vue.set(object, key, value)方法将响应属性添加到嵌套的对象上

    // Vue.set(object, key, value) 
    <template>
        <div>{{obj.k}}</div>
    </template>
    <script>
    export default {
        data() {
            return {
                obj: {
                    s: '1',
                    z: '2'
                }
            }   
        },
        mounted() {
            this.$set(this.obj, 'k', '3')
        }
    }
    </script>
    

    $set原理

    直接看源码

    function set(target: Array<any> | Object, key: any, val: any): any {
      // isUndef 是判断 target 是不是等于 undefined 或者 null 。
      //isPrimitive 是判断 target 的数据类型是不是 string、number、symbol、boolean 中的一种
      if (process.env.NODE_ENV !== 'production' &&
        (isUndef(target) || isPrimitive(target))
      ) {
        warn(`Cannot set reactive property on undefined, null, or primitive value: ${(target: any)}`)
      }
    
      // 数组的处理
      if (Array.isArray(target) && isValidArrayIndex(key)) {
        target.length = Math.max(target.length, key)
        target.splice(key, 1, val)
        return val
      }
    
      // 对象,并且该属性原来已存在于对象中,则直接更新
      if (key in target && !(key in Object.prototype)) {
        target[key] = val
        return val
      }
    
      // vue给响应式对象(比如 data 里定义的对象)都加了一个 __ob__ 属性,
      // 如果一个对象有这个 __ob__ 属性,那么就说明这个对象是响应式对象,我们修改对象已有属性的时候就会触发页面渲染。
      // 非 data 里定义的就不是响应式对象。
      const ob = (target: any).__ob__
    
      if (target._isVue || (ob && ob.vmCount)) {
        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) {
        target[key] = val
        return val
      }
    
      // 是响应式对象,进行依赖收集
      defineReactive(ob.value, key, val)
    
      // 触发更新视图
      ob.dep.notify()
      return val
    }
    
  • 相关阅读:
    微信公众平台--5.其他
    微信公众平台--4.接收事件推送消息
    微信公众平台--3.普通消息交互(发送与接收)
    微信公众平台--2.获取接口调用凭据
    微信公众平台--1.开发者接入
    PHP的几种缓存方式
    缓存时PHP读写文件的方法
    PHP接收post过来的xml数据
    PHP CURL上传文件
    Linux常用命令ps,kill
  • 原文地址:https://www.cnblogs.com/shizk/p/15456222.html
Copyright © 2011-2022 走看看