Vue之vue.$set()方法源码案例详解
在使用vue开发项目的过程中,经常会遇到这样的问题:当vue的data里边声明或者已经赋值过的对象或者数组(数组里边的值是对象)时,向对象中添加新的属性,如果更新此属性的值,是不会更新视图的。
这是因为新加入的属性不是响应式的,因此不会触发视图的更新,通常使用静态方法Vue.set()或者实例方法this.$set()解决 ,使用方式:
对象:this.$set(target,key, value)
数组:this.$set(target,index, value)
但不管是静态方法Vue.set()还是实例方法this.$set(),他们底层的实现逻辑是一样的,实现逻辑如下:
/** * Set a property on an object. Adds the new property and * triggers change notification if the property doesn't * already exist. */ export function set (target: Array<any> | Object, key: any, val: any): any { // 首先判断如果传入的目标对象是undefined, null, primitive(原始值),或抛出警告 if (process.env.NODE_ENV !== 'production' && (isUndef(target) || isPrimitive(target)) ) { warn(`Cannot set reactive property on undefined, null, or primitive value: ${(target: any)}`) } // 判断目标对象target是数组,并且key是合法的索引 if (Array.isArray(target) && isValidArrayIndex(key)) { // 取目标数组的length值和key中较大的值作为target的length属性 target.length = Math.max(target.length, key) // 通过splice对key位置的元素进行替换 target.splice(key, 1, val) return val } // 如果key在目标对象中已经存在,则直接赋值 if (key in target && !(key in Object.prototype)) { target[key] = val return val } // 获取target中的observer对象 const ob = (target: any).__ob__ // 如果target是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 } // 如果ob不存在,说明target不是响应式对象,直接赋值,不触发视图更新 if (!ob) { target[key] = val return val } // 如果ob存在,把key设置为响应式属性 defineReactive(ob.value, key, val) // 发送通知,触发视图更新 ob.dep.notify() return val }
以上是vue 中set方法的源码,在这里需要特别注意的是,在对数组进行处理时,所用的splice方法并不是数组本身的方法,而是在vue中封装的具有响应式的数组方法。
到此这篇关于Vue之vue.$set()方法源码案例详解的文章就介绍到这了,更多相关Vue之vue.$set()方法源码内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
vue element-ui el-cascader级联选择器数据回显的两种实现方法
这篇文章主要介绍了vue element-ui el-cascader级联选择器数据回显的两种实现方法,具有很好的参考价值,希望对大家有所帮助。2023-07-07详解vue2.0的Element UI的表格table列时间戳格式化
本篇文章主要介绍了详解vue2.0的Element UI的表格table列时间戳格式化,具有一定的参考价值,感兴趣的小伙伴们可以参考一下。2017-06-06在vue中使用axios实现post方式获取二进制流下载文件(实例代码)
这篇文章主要介绍了在vue中使用axios实现post方式获取二进制流下载文件的相关资料,需要的朋友可以参考下2019-12-12Vue2 特殊符号让人傻傻分不清 “:”、“.”、“@”、“#” 、“{{}}“ 、“$“,‘$bus‘,‘$e
:”是指令 “v-bind”的缩写“.”是修饰符 “@”是指令“v-on”的缩写 ,它用于监听 DOM 事件 “#”是v-slot的缩写,这篇文章主要介绍了Vue2 新手上路无处不在的特殊符号让人傻傻分不清“:”、“.”、“@”、“#” 、“{{}}“ 、“$“,$bus,$event,需要的朋友可以参考下2024-08-08
最新评论