美文网首页前端
Vue更新数组

Vue更新数组

作者: skoll | 来源:发表于2022-06-28 11:08 被阅读0次

    方法1 splice()

    1 .增删改查都能实现
    2 .实现原理

    const methodsToPatch = [
      'push',
      'pop',
      'shift',
      'unshift',
      'splice',
      'sort',
      'reverse'
    ]
    methodsToPatch.forEach(function (method) {
      // cache original method
      const original = arrayProto[method]
      def(arrayMethods, method, function mutator (...args) {
        const result = original.apply(this, args)
        const ob = this.__ob__
        let inserted
        switch (method) {
          case 'push':
          case 'unshift':
            inserted = args
            break
          case 'splice':
            inserted = args.slice(2)
            break
        }
        if (inserted) ob.observeArray(inserted)
        ob.dep.notify()
        return result
      })
    })
    

    1 .对这些方法包装,新增的数据,而且会把新加入的值变成响应式对象
    2 .手动调用依赖触发通知.
    3 .既然这里已经知道了触发的是什么操作,为啥还需要都diff操作呢??

    方法2 Vue.set==this.$set

    1 .用来主动触发一个响应

    this.data[1]='hello'
    //不会生效
    this.$set(this.data,1,'hello')
    Vue.set(this.data,1,'hello')
    //会生效
    

    2 .数组的时候,其实是在底层调用了splice方法

     if (Array.isArray(target) && isValidArrayIndex(key)) {
        target.length = Math.max(target.length, key)
        target.splice(key, 1, val)
        return val
      }
    

    3 .对象的时候

    如果之前有这个值的时候,换了值直接返回
    if (key in target && !(key in Object.prototype)) {
        target[key] = val
        return val
      }
    
    //如果没有的话
    
    //看属性是不是添加在了根级,加在根级就报错,__ob__指的是Observer对象。vmCount用来表示当前对象是否是根级属性。_isVue用来表示是否是Vue实例。上面说过target不能是根级属性或者Vue实例
    if (!ob) {
        target[key] = val
        return val
      }
      defineReactive(ob.value, key, val)
      ob.dep.notify()
      return val
    //绑定数据,然后触发检测
    

    2.0 和3.0 nwe 出来的东西还不一样啊


    image.png

    //可以看到,在根部添加一个新的key值,虽然没有报错,但是实际没有绑定到,也就是说如果要用到,还是提前定义吧.不然别人也不知道有这个变量

    为什么会有Vue.set这个操作呢?

    image.png

    1 .每次修改都是全量的吧,深层嵌套的怎么改,每次只想改一个key,现在是必须全部替换.难道一定要拆分组件么?

    Vue.set(app,"love",{home:{'age':"lala",work:"123"}})
    //比如这个新增一个属性的时候,还要必须先把原来的属性加上么.这样写很累的吧
    
    var vm=new Vue({
        el:'#test',
        data:{
            //data中已经存在info根属性
            info:{
                name:'小明';
            }
        }
    });
    //给info添加一个性别属性
    Vue.set(vm.info,'sex','男');
    //似乎不是
    

    2 .向响应式对象中添加一个 property,并确保这个新 property 同样是响应式的,且触发视图更新。它必须用于向响应式对象上添加新 property,因为 Vue 无法探测普通的新增 property比如this.myObject.newProperty='hi'

    3 .注意对象不能是 Vue 实例,或者 Vue 实例的根数据对象。
    4 .Vue.set新增的变量,Vue tools能否看到,这个是属于data里面的吧
    5 .为啥会有动态添加新属性的需求呢?不都是初始化的时候写在里面么?

    1 .数据是一个对象,但是这个对象的值是不确定的,或者需要及时生成的
    2 .从这里看他确实和react完全不同,react可以是直接setDate一个新对象进去,他这里是无法直接替换新对象??
    

    6 .Vue.set是定义在构造函数上的,this.$set定义在原型对象上
    7 .受 ES5 的限制,Vue.js 不能检测到对象属性的添加或删除。因为 Vue.js 在初始化实例时将属性转为 getter/setter,所以 属性必须在 data 对象上才能让 Vue.js 转换它,才能让它是响应的

    vm.$forceUpdate

    1 .强制使Vue实例渲染,其实this.list[1]="xxx"这种操作已经修改了数据,但是这种修改没有触发到对应更新的钩子函数,所以使用这个函数可以强制使页面刷新
    2 .尽量避免使用这个函数,如果你使用这个,多半是使用不正确
    3 .

    相关文章

      网友评论

        本文标题:Vue更新数组

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