Vue 怎么用 vm.$set() 解决对象新增属性不能响应的问题 ?
受现代 JavaScript 的限制 ,Vue 无法检测到对象属性的添加或删除。
由于 Vue 会在初始化实例时对属性执行 getter/setter 转化,所以属性必须在 data 对象上存在才能让 Vue 将它转换为响应式的。
但是 Vue 提供了
Vue.set (object, propertyName, value) / vm.$set (object, propertyName, value)
来实现为对象添加响应式属性,那框架本身是如何实现的呢?
我们查看对应的 Vue 源码:
vue/src/core/instance/index.js
export function set (target: Array<any> | Object, key: any, val: any): any {
// target 为数组
if (Array.isArray(target) && isValidArrayIndex(key)) {
// 修改数组的长度, 避免索引>数组长度导致splcie()执行有误
target.length = Math.max(target.length, key)
// 利用数组的splice变异方法触发响应式
target.splice(key, 1, val)
return val
}
// key 已经存在,直接修改属性值
if (key in target && !(key in Object.prototype)) {
target[key] = val
return val
}
const ob = (target: any).__ob__
// target 本身就不是响应式数据, 直接赋值
if (!ob) {
target[key] = val
return val
}
// 对属性进行响应式处理
defineReactive(ob.value, key, val)
ob.dep.notify()
return val
}
我们阅读以上源码可知,vm.$set 的实现原理是:
- 如果目标是数组,直接使用数组的 splice 方法触发相应式;
- 如果目标是对象,会先判读属性是否存在、对象是否是响应式,最终如果要对属性进行响应式处理,则是通过调用 defineReactive 方法进行响应式处理( defineReactive 方法就是 Vue 在初始化对象时,给对象属性采用 Object.defineProperty 动态添加 getter 和 setter 的功能所调用的方法)
Vue 怎么用 vm.$set() 解决对象新增属性不能响应的问题 ?的更多相关文章
- Vue-给对象新增属性(使用Vue.$set())
在开发过程中,我们时常会遇到这样一种情况:当vue的data里边声明或者已经赋值过的对象或者数组(数组里边的值是对象)时,向对象中添加新的属性,如果更新此属性的值,是不会更新视图的. 根据官方文档定义 ...
- 关于vue给对象新增属性页面不会动态更新
不知道大家有没有遇到过这个问题,当我们给data里边声明或者已经赋值过的对象或者数组,添加新的属性时,如果更新此属性的值是不会动态更新视图的. $set 看以下实例: 我们开始给drug_list追加 ...
- jquery ajax 返回的json对象 新增属性值(干货)
$.ajax({ type:"GEt'; url:"你的地址", data:{"你的字段","字段值"} success:funt ...
- 针对vue中请求数据对象新添加的属性不能响应式的解决方法
1.需要给对象添加属性时,不能采用传统的obj.属性=值,obj[属性]=值 来添加属性,在vue页面时需要这样使用 this.$set(obj,"propertyName",&q ...
- 关于 vue 不能 watch 数组变化 和 对象变化的解决方案
原文地址:关于 vue 不能 watch 数组变化 和 对象变化的解决方案 vue 监听数组和对象的变化 vue 监听数组 vue 实际上可以监听数组变化,比如: data () { return { ...
- 解决vuejs 创建数据后设置对象的属性实现不了双向绑定问题
抛出踩坑:vue创建后的数据,自定义设置对象的属性,实现不了双向绑定 当业务场景,需要在请求接口数据新增自定义的属性 let foodList = [ {title: '回锅肉', price: 99 ...
- vue新增属性是否会响应式更新?
原文地址 在开发过程中,我们时常会遇到这样一种情况:当vue的data里边声明或者已经赋值过的对象或者数组(数组里边的值是对象)时,向对象中添加新的属性,如果更新此属性的值,是不会更新视图的. 根据官 ...
- AppleWatch开发教程之Watch应用对象新增内容介绍以及编写运行代码
AppleWatch开发教程之Watch应用对象新增内容介绍以及编写运行代码 添加Watch应用对象时新增内容介绍 Watch应用对象添加到创建的项目中后,会包含两个部分:Watch App 和 Wa ...
- 在vue中使用watch监听对象或数组
最近发现在vue中使用watch监听对象或者数组时,当数组或者对象只是单一的值改变时,并不会出发watch中的事件. 在找问题过程中,发现当数组使用push一类的方法时,会触发watch,如果只是单一 ...
- Vue 给对象添加属性
坑真多,没想到很多小细节都 改了,我添加个属性都 折腾了半天才看明白原因 Vue.set(row,"isEdit",false); //给row对象新增一个isEdit的属性.
随机推荐
- 删除字符串A中与字符串B相同的字符
/** * file name:DelDestChar.c * author : liaojx2016@126.com * date : 2024-05-06 * function : Delete ...
- C语言:约瑟夫问题——使用循环链表解决
传说有30个乘客同乘一条船,因为严重超载,加上风浪水作,危险万分.船长告诉乘客,只有将全船一半的乘客投入海 中,其余人才能幸免于难.他们约定了一个规则:30个人围成一圈,由第一个人数起,依次报数,数到 ...
- keycloak~正确让api接口支持跨域
相关参考 https://leejjon.medium.com/how-to-allow-cross-origin-requests-in-a-jax-rs-microservice-d2a6aa2d ...
- 三:nacos的配置中心
配置中心的使用: 编辑当前项目的pom.xml,加入必要的依赖配置 <!-- spring-cloud-alibaba-dependencies 依赖同注册中心 --> <depen ...
- Must use PackageReference 解决办法
Must use PackageReference 这是因为 .net framework的项目 在nuget时,引用到了 .net core 下的包. 解决办法,把之前引用的相关包全部在nuget上 ...
- 个人记录:连接、查询、写入PG数据库类文件
# --coding:utf-8-- import pandas as pd import yaml from sqlalchemy import create_engine import psyco ...
- 几个公司wiki知识库调研和感悟
@ 目录 需求背景 具体实现 经验&吐槽 小结 需求背景 公司准备做一个知识库,我这边调研了几个项目,如下 第一个是我们耳熟能详的confluence,但是好想要收费,先搁置 第二个是mind ...
- EF MYSQL DB FIRST 出现2次数据库名
环境:使用ADO设计器添加的数据库实体,运行时出现 :Table 'world.world.city' doesn't exist . world 是mysql的演示数据库. MySql.Data.E ...
- 打开 gpedit.msc 组策略时弹出错误提示,"找不到资源 string.Advanced_EnableSSL3Fallback ”。
原因是升级到 IE9 或者 IE 11 语言包没有及时更新. 解决方案一:用360再打补丁. 方案二:未尝试. https://www.microsoft.com/en-us/download/con ...
- vitepress使用createContentLoader时遇到["vitepress" resolved to an ESM file. ESM file cannot be loaded by `require`.]报错
在使用vitepress构建一个所有博客的概览页的时候,使用到了createContentLoader这个api,但是在index.data.ts中定义并导出后,在md文件中调用遇到了下面这个问题: ...