Vue.set()的使用,以及对其进行深入解析
创始人
2024-05-05 05:27:28
0

目录

Vue.set()使用

Vue.delete()的使用

 Vue.set()方法原理解析

总结

Vue.set()使用

vue 在实例上添加新的属性的时候,该属性,并不是响应式的。同样删除某一属性的时候,也不会实时渲染到页面上。

        比如:

 

年龄:{{obj.age? obj.age: "无"}}

        ···········      

 data() {

            return {        

                obj:{ name:"Lena", id:1 },

            }

          }

页面上 显示的是  年龄:无   现在需要添加一个响应式的属性 age 。


效果:

通过 this.obj.age= 20 ,控制台打印已经有了该属性,并没有渲染到页面上。 可见,这种方式添加的属性 age 并不是响应式的。

使用Vue.set() ,更改add()方法:

add(){Vue.set(this.obj,'age', '20')},

效果:

 因为vue不能检测到对象属性的添加或者删除,只有在data对象上存在的属性是响应式的,所以要使用Vue.set()方法将响应式属性添加到对象上。同样的道理,删除对象 Vue.delete也是如此。

Vue.delete()的使用



效果:

 del() 方法如果是下面两种,同样不是响应式的。

del(){

      delete this.obj.age

    },

或者:

del(){

      this.obj = { name:"Lena", id:1 }

    },

 Vue.set()方法原理解析

        我们找到封装set方法的地方:.........\node_modules\vue\src\core\observer\index.js

 找到封装的set方法:

export function set (target: Array | 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)}`)}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] = valreturn val}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] = valreturn val}defineReactive(ob.value, key, val)ob.dep.notify()return val
}

对象调用:Vue.set( target ,'age', 20 ) 

数组调用Vue.set( array , 0,  20 )  //数组对象,索引,值


        首先是判断是否是开发环境并且 对象是否被定义isUndef(target)或者是否是基础类型isPrimitive(target),否则会报错:

`Cannot set reactive property on undefined, null, or primitive value: ${(target: any)}`

if (process.env.NODE_ENV !== 'production' &&

    (isUndef(target) || isPrimitive(target))

  )


        如果是数组的话,调用重写的splice()方法,可以更新视图。

        isValidArrayIndex(key)方法用来验证是否是一个有效的数组索引, 其实就是验证是否是一个非无穷大的正整数。

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的时候,就会报错。

如果本身就不是响应式的,只需要直接赋值即可。

const ob = (target: any).__ob__//如果是Vue实例,或者是根数据data的时候,就会报错。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] = valreturn val}defineReactive(ob.value, key, val)ob.dep.notify()return val

排除各种不合适的,最后给当前对象定义一个属性:defineReactive(ob.value, key, val) 相当于用了 Object.defineProperty 重新定义了一下。

最后,手动通知视图更新:ob.dep.notify()

总结

这个 set方法,对于数组来说,调用的就是splice,对于对象来说,使用的就是defineReactive,再添加了一个手动的视图更新。这就是set的原理。

相关内容

热门资讯

喜欢穿一身黑的男生性格(喜欢穿... 今天百科达人给各位分享喜欢穿一身黑的男生性格的知识,其中也会对喜欢穿一身黑衣服的男人人好相处吗进行解...
发春是什么意思(思春和发春是什... 本篇文章极速百科给大家谈谈发春是什么意思,以及思春和发春是什么意思对应的知识点,希望对各位有所帮助,...
网络用语zl是什么意思(zl是... 今天给各位分享网络用语zl是什么意思的知识,其中也会对zl是啥意思是什么网络用语进行解释,如果能碰巧...
为什么酷狗音乐自己唱的歌不能下... 本篇文章极速百科小编给大家谈谈为什么酷狗音乐自己唱的歌不能下载到本地?,以及为什么酷狗下载的歌曲不是...
家里可以做假山养金鱼吗(假山能... 今天百科达人给各位分享家里可以做假山养金鱼吗的知识,其中也会对假山能放鱼缸里吗进行解释,如果能碰巧解...
华为下载未安装的文件去哪找(华... 今天百科达人给各位分享华为下载未安装的文件去哪找的知识,其中也会对华为下载未安装的文件去哪找到进行解...
四分五裂是什么生肖什么动物(四... 本篇文章极速百科小编给大家谈谈四分五裂是什么生肖什么动物,以及四分五裂打一生肖是什么对应的知识点,希...
怎么往应用助手里添加应用(应用... 今天百科达人给各位分享怎么往应用助手里添加应用的知识,其中也会对应用助手怎么添加微信进行解释,如果能...
客厅放八骏马摆件可以吗(家里摆... 今天给各位分享客厅放八骏马摆件可以吗的知识,其中也会对家里摆八骏马摆件好吗进行解释,如果能碰巧解决你...
苏州离哪个飞机场近(苏州离哪个... 本篇文章极速百科小编给大家谈谈苏州离哪个飞机场近,以及苏州离哪个飞机场近点对应的知识点,希望对各位有...