首页 > 编程语言 >Vue $set 源码解析(保证你也能看懂)

Vue $set 源码解析(保证你也能看懂)

时间:2023-01-25 20:07:59浏览次数:37  
标签:&& set return target val ob Vue 源码 key

首先我们看文档有这个例子

Vue $set 源码解析(保证你也能看懂)_数组

下面是vue $set部分源码

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
}
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()

我们先看第一块

if (process.env.NODE_ENV !== 'production' && (isUndef(target) || isPrimitive(target)) ) { warn(`Cannot set reactive property on undefined, null, or primitive value: ${(target: any)}`)

我们先看第一段代码 isUndef和isPrimitive方法,从名字就可以看出,isUndef是判断target是不是等于undefined或者null。isPrimitive是判断target的数据类型是不是string、number、symbol、boolean中的一种。所以这里的意思是如果当前环境不是生产环境并且 isUndef(target) || isPrimitive(target) 为真的时候,那么就抛出错误警告。

//----------------------------------

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

接着我们看第二段

isArray 判断是不是数组,并且key的值是有效的数组索引。

然后将target数组的长度设置为target.length和key中的最大值,为了防止我们传入key下标超过数组长度导致报错。

尤玉溪重写了vue 的原型 arrayMethods 里面监听了七个方法 他文档上有提到

这里使用splice是arrayMethods提供的7个方法中的一种 来做到替换数组的数据

//-------------------------------------

if (key in target && !(key in Object.prototype)) {
target[key] = val
return val
}

我们来看第三段

他判断了这个key是不是当前对象的key 和 这个key 不是object原型的key

说明这个key本来就在对象上面已经定义过了的,直接修改值就可以了,可以自动触发响应

//------------------------------

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
}

我们来看第四段

我们可以看到 他给对象添加了一个__obj__属性如果一个对象有这个​​__ob__​​属性,那么就说明这个对象是响应式对象,我们修改对象已有属性的时候就会触发页面渲染

​if (!ob)​​为真说明当前的target对象不是响应式对象,不需要响应,那么直接赋值返回即可

defineReactive(ob.value, key, val)
ob.dep.notify()
return val

最后一段

这里才是vue.set()真正处理对象的地方。defineReactive(ob.value, key, val)的意思是给新加的属性添加依赖,以后再直接修改这个新的属性的时候就会触发页面渲染。 ob.dep.notify()这句代码的意思是触发当前的依赖(这里的依赖依然可以理解成渲染函数),所以页面就会进行重新渲染。

标签:&&,set,return,target,val,ob,Vue,源码,key
From: https://blog.51cto.com/u_13463935/6022754

相关文章

  • Vue3 proxy 解决跨域
    1.首先我们先了解一下什么是跨域主要是出于浏览器的同源策略限制,它是浏览器最核心也最基本的安全功能。当一个请求url的协议、域名、端口三者之间任意一个与当前页面url不......
  • vue钩子函数
    钩子函数按照组件生命周期的过程分为,挂载阶段=>更新阶段=>销毁阶段。每个阶段对应的钩子函数挂载阶段:beforeCreate、created、beforeMounted、mounted更新阶段:beforeUpd......
  • 说一说Vuex是什么,每个属性是干嘛的,如何使用 ?
    Vue的概念Vuex是集中管理项目的公共数据的2.vuex的属性:state:保存数据状态的仓库getters:对state数据进行计算,类似于计算属性(依赖数据发生变化才会重新计算)action:发......
  • Vue2.0 双向绑定的原理与缺陷?
    原理Object.defineProperty、getter、setter标准回答Vue响应式指的是:组件的data发生变化,立刻触发试图的更新原理:Vue采用数据劫持结合发布者-订阅者模式的方式来实现数......
  • Vue3.0 实现数据双向绑定的方法
    ue3.0是通过Proxy实现的数据双向绑定,Proxy是ES6中新增的一个特性,实现的过程是在目标对象之前设置了一层“拦截”,外界对该对象的访问,都必须先通过这层拦截,因此提供了一种机......
  • Laravel9+Vue+ElementUI后台快速开发框架
    项目介绍一款PHP语言基于Laravel9.x、Vue、ElementUI等框架精心打造的一款模块化、插件化、高性能的前后端分离架构敏捷开发框架,可用于快速搭建前后端分离后台管理系统,本......
  • Laravel9+Vue+ElementUI快速搭建后台管理系统
    项目介绍一款PHP语言基于Laravel9.x、Vue、ElementUI等框架精心打造的一款模块化、插件化、高性能的前后端分离架构敏捷开发框架,可用于快速搭建前后端分离后台管理系统,本......
  • 一款Laravel9+Vue+ElementUI后台管理框架
    项目介绍一款PHP语言基于Laravel9.x、Vue、ElementUI等框架精心打造的一款模块化、插件化、高性能的前后端分离架构敏捷开发框架,可用于快速搭建前后端分离后台管理系统,本......
  • RK3568源码编译与交叉编译环境搭建
    本篇进行飞凌OK3568-C开发板的Linux系统开发需要用的软件交叉编译环境的配置。对于软件开发,如果只是使用C/C++代码,则在自己的Ubuntu虚拟机中添加RK3568对应的交叉编译器(gcc......
  • vue-grid-layout数据可视化图表面板优化过程所遇问题汇总
    对于drag事件不熟悉的,请先阅读:《drag事件详解:html5鼠标拖动排序及resize实现方案分析及实践》之前老项目grafana面板,如下图所示(GEM添加图表是直接到图表编辑,编辑完成后自......