Vue之vue.$set()方法源码案例详解_vue.js

来源:脚本之家  责任编辑:小易  

在使用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.$set 失效的坑 问题发现及解决方案vue 中this.$set 动态绑定数据的案例讲解Vue——解决报错 Computed property "****" was assigned to but it has no setter.vue3.0中setup使用(两种用法)浅谈vue中resetFields()使用注意事项

  • 本文相关:
  • vue 实现登录界面验证码功能
  • 详解vue-cli 3.0 build包太大导致首屏过长的解决方案
  • vue实现用户登录及token验证
  • vue移动端使用appclound拉起支付宝支付的实现方法
  • vue component组件使用方法详解
  • vue模块拖拽实现示例代码
  • vue 路由切换时页面内容没有重新加载的解决方法
  • vue使用axios出现options请求方法
  • vue实现短信验证码登录功能(流程详解)
  • vue学习教程之带你一步步详细解析vue-cli
  • Vue.set()实现数据动态响应的方法
  • vue App.vue中的公共组件改变值触发其他组件或.vue页面监听
  • 基于vue,vue-router, vuex及addRoutes进行权限控制问题
  • 关于Vue源码vm.$watch()内部原理详解
  • Vue.js每天必学之计算属性computed与$watch
  • 简单了解vue.js数组的常用操作
  • 使用的是vue2.0,请问.vue文件中如何使用echarts
  • 使用的是vue2.0,请问.vue文件中如何使用echarts
  • Angular和Vue双向数据绑定的实现原理(重点是vue的双向绑定)
  • 网站首页网页制作脚本下载服务器操作系统网站运营平面设计媒体动画电脑基础硬件教程网络安全yui.ext相关prototypejqueryangularjsjsonlib_jsjs面向对象extjsmootoolsseajsdojovue.jsbackbone.jsreact其它首页javascriptjavascript类库vue.$set 失效的坑 问题发现及解决方案vue 中this.$set 动态绑定数据的案例讲解vue——解决报错 computed property "****" was assigned to but it has no setter.vue3.0中setup使用(两种用法)浅谈vue中resetfields()使用注意事项vue 实现登录界面验证码功能详解vue-cli 3.0 build包太大导致首屏过长的解决方案vue实现用户登录及token验证vue移动端使用appclound拉起支付宝支付的实现方法vue component组件使用方法详解vue模块拖拽实现示例代码vue 路由切换时页面内容没有重新加载的解决方法vue使用axios出现options请求方法vue实现短信验证码登录功能(流程详解)vue学习教程之带你一步步详细解析vue-clivue引用js文件的多种方式(推荐)详解vue 路由跳转四种方式 (带参vue之父子组件间通信实例讲解(prvue项目刷新当前页面的三种方法vue跳转页面的几种方法(推荐)vue props用法详解(小结)vue元素的隐藏和显示(v-show指令vue实现文件上传功能简单理解vue中props属性element-ui中select组件绑定值改实例详解vue中的$root和$parentvue 中使用vue2-highcharts实现top功能的vue渲染方式render和template的区别vue-cli —— 如何局部修改element样式利用electron简单撸一个markdown编辑器的vue.js实现大转盘抽奖总结及实现思路解决vue项目f5刷新mounted里的函数不执行vue + element-ui实现简洁的导入导出功能详解vue-cli 脚手架 安装vue.js实现文章评论和回复评论功能
    免责声明 - 关于我们 - 联系我们 - 广告联系 - 友情链接 - 帮助中心 - 频道导航
    Copyright © 2017 www.zgxue.com All Rights Reserved