IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> vue源码--$set/$delete -> 正文阅读

[JavaScript知识库]vue源码--$set/$delete

$set

用法

set 是全局 Vue.set 的别名。

set(target, propertyName/index, value)

作用

Vue 中对于对象新增的属性或者是数组新增的下标都是不能够监听到的,为了保障新的属性同样是响应式的,且触发视图更新,需要借助 this.$set 来新增属性。

对象不能是 Vue 实例或者是 Vue 实例的根数据对象。

原理

// src/core/observer/index.js

function set (target: Array<any> | Object, key: any, val: any): any {
  // 判断非生产环境下传入的 target 是否为 undefined、null 或原始类型
  if (process.env.NODE_ENV !== 'production' &&
    (isUndef(target) || isPrimitive(target))
  ) {
    // 如果是,就抛出警告
    warn(`Cannot set reactive property on undefined, null, or primitive value: ${(target: any)}`)
  }
  // 如果传入的是数组 并且 key 是有效的数组索引。
  if (Array.isArray(target) && isValidArrayIndex(key)) {
    // 取数组长度和 key 这两者最大的值作为数组的新长度
    target.length = Math.max(target.length, key)
    // 数组的splice方法将传入的索引key对应的val值添加进数组
    target.splice(key, 1, val)
    // 把值返回
    return val
  }
  // 如果是对象
  //首先判断 key 是否存在于 target 中。
  if (key in target && !(key in Object.prototype)) {
    // 修改操作, 只修改属性值即可。
    target[key] = val
    return val
  }
  // __ob__ 标志着是否已经是响应式的了。
  const ob = (target: any).__ob__
  // target 是否是 Vue 实例,或者 vue 实例的根数据对象
  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
  }
  // target 不是一个响应式对象
  if (!ob) {
    // 只需要给 target 添加属性
    target[key] = val
    return val
  }
  // 是对象,并且是响应式的,将新属性添加到 target 上。
  defineReactive(ob.value, key, val)
  // 通知依赖跟新
  ob.dep.notify()
  // 返回值
  return val
}

可以看出来,就是通过不断的判断,先判断 target 的类型是否为 null、undefined、原始数据类型。然后判断是否为数组,然后判断是否为对象.

$delete

vm.$delete 是全局 Vue.delete 别名。

vm.$delete(target, propertyName, index)

删除对象的属性,能够删除后触发视图的更新。属性被删除是不能够被检测到的。

源码

function del (target: Array<any> | Object, key: any) {
  // 判断非生产环境下传入的 target 是否为 undefined、null 或原始类型
  if (process.env.NODE_ENV !== 'production' &&
    (isUndef(target) || isPrimitive(target))
  ) {
    // 警告
    warn(`Cannot delete reactive property on undefined, null, or primitive value: ${(target: any)}`)
  }
  // 如果 target 是数组, 并且 key 是有效索引
  if (Array.isArray(target) && isValidArrayIndex(key)) {
    // 使用 splice 来删除掉 key 的数组元素。
    target.splice(key, 1)
    return
  }
  // __ob__ 标志着是否已经是响应式的了。
  const ob = (target: any).__ob__
  // target 是否是 Vue 实例,或者 vue 实例的根数据对象
  if (target._isVue || (ob && ob.vmCount)) {
    // 警告
    process.env.NODE_ENV !== 'production' && warn(
      'Avoid deleting properties on a Vue instance or its root $data ' +
      '- just set it to null.'
    )
    return
  }
  // key 是否存在于 target 上, 不存在就不用删除
  if (!hasOwn(target, key)) {
    return
  }
  // 从属性中删除
  delete target[key]
  // 当前的 target 是否是响应式对象
  if (!ob) {
    // 如果不是响应式就删除后直接返回
    return
  }
  // 是响应式的,就通知依赖更新
  ob.dep.notify()
}

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-04-27 11:15:01  更:2022-04-27 11:15:58 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 1:24:34-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码