首页 > 其他分享 >Vue进阶(九十八):Vue.set() 和 this.$set()

Vue进阶(九十八):Vue.set() 和 this.$set()

时间:2023-05-21 10:05:00浏览次数:30  
标签:Vue target val 九十八 set key data

(文章目录)

一、应用场景

有时候我们会看到如下代码: 在这里插入图片描述 在我们使用vue进行开发的过程中,可能会遇到这样一种情况:当创建vue实例后,再次给对象赋值时,发现数据并不会自动更新到视图上去; 当我们去阅读vue文档的时候,会发现有这么一句话:如果在实例创建之后添加新的属性到实例上,它不会触发视图更新。 如下代码,给 student对象新增 age 属性。

data () {
  return {
    student: {
      name: '',
      sex: ''
    }
  }
}
mounted () { // ——钩子函数,实例挂载之后
  this.student.age = 24
}

二、原因分析

ES5 的限制,Vue.js 不能检测到对象属性的添加或删除,即Vue未做到脏数据检查。因为 Vue.js 在初始化实例时将属性转为 getter/setter,所以属性必须在 data 对象上才能让 Vue.js 转换它,才能让它是响应的。

正确写法:this.$set(this.data,”key”,value')

mounted () {
  this.$set(this.student,"age", 24)
}

Vue 不允许动态添加根级响应式属性。

例如:

const app = new Vue({
  data: {
    a: 1
  }
  // render: h => h(Suduko)
}).$mount('#app1')

Vue.set(app.data, 'b', 2)

此时控制台会报错: 在这里插入图片描述 只可以使用 Vue.set(object, propertyName, value) 方法向嵌套对象添加响应式属性,例如

var vm=new Vue({
    el:'#test',
    data:{
        //data中已经存在info根属性
        info:{
            name:'小明';
        }
    }
});
//给info添加一个性别属性
Vue.set(vm.info,'sex','男');

有童鞋可能会问之前使用过Vue.set()this.$set()Vue.set有什么联系呢?

三、Vue.set() 和 this.$set() 实现原理

源码分析

先来看看Vue.set()源码:

import { set } from '../observer/index'

...
Vue.set = set
...

再看看this.$set()源码:

import { set } from '../observer/index'

...
Vue.prototype.$set = set
...

我们发现Vue.set()和this.$set()这两个api的实现原理基本一模一样,都使用了set()set()函数是从 ../observer/index 文件中导出的,区别在于:Vue.set()是将set函数绑定在Vue构造函数上,this.$set()set函数绑定在Vue原型上。

再来看下set源码:

function set (target: Array<any> | 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] = 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()
  return val
}

我们发现set函数接收三个参数分别为 target、key、val,其中target的值为数组或者对象,这正好和官网给出的调用Vue.set()时传入的参数对应上。 在这里插入图片描述

四、延伸阅读

上文讲解了应用Vue.setthis.$set 实现动态添加对象属性,视图层随之动态渲染。其实,还有另外一种方法可以解决以上问题,那就是通过添加 this.$forceUpdate() 在修改数据后执行即可。有关 this.$forceUpdate() 的讲解,详参博文

标签:Vue,target,val,九十八,set,key,data
From: https://blog.51cto.com/shq5785/6318618

相关文章

  • vue中输入密码带图标可见不可见切换
    data(){return{userName:"",pswd:"",loginDisabled:false,labelPosition:"top",passwordType:'password',passwordIcon:require('@m/assets/images/bukejian.png')......
  • Set集合
    set集合一直以来,JS只能使用数组和对象来保存多个数据,缺乏像其他语言那样拥有丰富的集合类型。因此,ES6新增了两种集合类型(set和map),用于在不同的场景中发挥作用。set用于存放不重复的数据如何创建set集合newSet();//创建一个没有任何内容的set集合newSet(iterable);......
  • Ubuntu桌面下Vue开发环境搭建
    Ubuntu桌面下Vue开发环境搭建node环境node安装node官网下载node安装包:node-v18.16.0-linux-x64.tar.xz#解压sudotar-xvJfnode-v18.16.0-linux-x64.tar.xz-C/usr/local/cd/usr/local/sudomvnode-v18.16.0-linux-x64/nodejs#配置环境变量cd/etc/profile.d/......
  • vue3 +leaflet + 天地图
    vue3使用leafletnpminstallleaflet-D如果使用了tsnpmi--save-dev@types/leaflet//使用了ts需要下载声明类型//更具需要获取不通过类型的urlfunctiongetUrl(type:string){interfaceMyObject{[key:string]:Array<string>;}letobj:MyObject=......
  • springboot基于vue的MOBA类游戏攻略分享平台、游戏资讯分享平台,附源码+数据库+lw文档+
    1、项目介绍任何系统都要遵循系统设计的基本流程,本系统也不例外,同样需要经过市场调研,需求分析,概要设计,详细设计,编码,测试这些步骤,基于java语言设计并实现了MOBA类游戏攻略分享平台。该系统基于B/S即所谓浏览器/服务器模式,应用java技术,选择MySQL作为后台数据库。系统主要包括系统首......
  • 记录--Vue中如何导出excel表格
    这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助一、导出静态数据1、安装vue-json-excelnpm i vue-json-excel注意,此插件对node有版本要求,安装失败检查一下报错是否由于node版本造成!2、引入并注册组件(以全局为例)importVuefrom"vue";importJsonExce......
  • vue面试题汇总1
    Vue中什么是组件?答:在Vue中,组件是可重用的代码块,可以包含HTML、CSS和JavaScript,并具有自己的状态和生命周期。可以使用组件来构建UI界面并管理应用程序的状态。简要描述Vue的数据绑定方式。答:Vue使用双向数据绑定(two-waydatabinding)方式将模型数据和视图绑定在一起。当视图中的数......
  • Vue进阶(九十七):对象动态添加属性和值
    (文章目录)一、背景Vue规定不允许直接修改props或者data属性,必须使用Vue.set方法。Vue.set方法用来修改对象属性。如果要增加属性所属对象是响应式的,该方法可以确保属性被创建后也是响应式的,同时触发视图更新。二、基础知识注:修改的对象必须为响应式对象,且操作响应式对象的属......
  • 【vue】div标签和template标签使用区别
       ......
  • ruoyi-vue接入钉钉,作为h5微应用
    ruoyi-vue接入钉钉,作为h5微应用https://blog.csdn.net/jiaodacailei/article/details/1247099141.安装依赖在ruoyi-ui目录,npm安装依赖:npminstalldingtalk-jsapi--save2.定义全局钉钉企业IDruoyi-ui/.env.developmentruoyi-ui/.env.productionruoyi-ui/.env.staging#......