「Vue面试题」动态给vue的data添加一个新的属性时会发生什么?怎样去解决的?

news2024/9/30 15:35:05

在这里插入图片描述

一、直接添加属性的问题

我们从一个例子开始

定义一个p标签,通过v-for指令进行遍历

然后给botton标签绑定点击事件,我们预期点击按钮时,数据新增一个属性,界面也 新增一行

<p v-for="(value,key) in item" :key="key">
    {{ value }}
</p>
<button @click="addProperty">动态添加新属性</button>

实例化一个vue实例,定义data属性和methods方法

const app = new Vue({
    el:"#app",
       data:()=>{
           item:{
            oldProperty:"旧属性"
        }
    },
    methods:{
        addProperty(){
            this.items.newProperty = "新属性"  // 为items添加新属性
            console.log(this.items)  // 输出带有newProperty的items
        }
    }
})

点击按钮,发现结果不及预期,数据虽然更新了(console打印出了新属性),但页面并没有更新

二、原理分析

为什么产生上面的情况呢?

下面来分析一下

vue2是用过Object.defineProperty实现数据响应式

const obj = {}
Object.defineProperty(obj, 'foo', {
        get() {
            console.log(`get foo:${val}`);
            return val
        },
        set(newVal) {
            if (newVal !== val) {
                console.log(`set foo:${newVal}`);
                val = newVal
            }
        }
    })
}

当我们访问foo属性或者设置foo值的时候都能够触发settergetter

obj.foo   
obj.foo = 'new'

但是我们为obj添加新属性的时候,却无法触发事件属性的拦截

obj.bar  = '新属性'

原因是一开始objfoo属性被设成了响应式数据,而bar是后面新增的属性,并没有通过Object.defineProperty设置成响应式数据

三、解决方案

Vue 不允许在已经创建的实例上动态添加新的响应式属性

若想实现数据与视图同步更新,可采取下面三种解决方案:

  • Vue.set()
  • Object.assign()
  • $forcecUpdated()

Vue.set()

Vue.set( target, propertyName/index, value )

参数

  • {Object | Array} target
  • {string | number} propertyName/index
  • {any} value

返回值:设置的值

通过Vue.set向响应式对象中添加一个property,并确保这个新 property 同样是响应式的,且触发视图更新

关于Vue.set源码(省略了很多与本节不相关的代码)

源码位置:src\core\observer\index.js

function set (target: Array<any> | Object, key: any, val: any): any {
  ...
  defineReactive(ob.value, key, val)
  ob.dep.notify()
  return val
}

这里无非再次调用defineReactive方法,实现新增属性的响应式

关于defineReactive方法,内部还是通过Object.defineProperty实现属性拦截

大致代码如下:

function defineReactive(obj, key, val) {
    Object.defineProperty(obj, key, {
        get() {
            console.log(`get ${key}:${val}`);
            return val
        },
        set(newVal) {
            if (newVal !== val) {
                console.log(`set ${key}:${newVal}`);
                val = newVal
            }
        }
    })
}

Object.assign()

直接使用Object.assign()添加到对象的新属性不会触发更新

应创建一个新的对象,合并原对象和混入对象的属性

this.someObject = Object.assign({},this.someObject,{newProperty1:1,newProperty2:2 ...})

$forceUpdate

如果你发现你自己需要在 Vue 中做一次强制更新,99.9% 的情况,是你在某个地方做错了事

$forceUpdate迫使 Vue 实例重新渲染

PS:仅仅影响实例本身和插入插槽内容的子组件,而不是所有子组件。

小结

  • 如果为对象添加少量的新属性,可以直接采用Vue.set()
  • 如果需要为新对象添加大量的新属性,则通过Object.assign()创建新对象
  • 如果你实在不知道怎么操作时,可采取$forceUpdate()进行强制刷新 (不建议)

PS:vue3是用过proxy实现数据响应式的,直接动态添加新属性仍可以实现数据响应式

可以直接采用Vue.set()

  • 如果需要为新对象添加大量的新属性,则通过Object.assign()创建新对象
  • 如果你实在不知道怎么操作时,可采取$forceUpdate()进行强制刷新 (不建议)

PS:vue3是用过proxy实现数据响应式的,直接动态添加新属性仍可以实现数据响应式

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/398370.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Esp8266学习4. 基于Arduino的PWM与红外信号处理

Esp8266学习4. 基于Arduino的PWM与红外信号处理一、基本概念1. PWM2. ESP8266 的 PWM功能3. node-mcu 引脚图4. 模拟写入&#xff08;1&#xff09;analogWrite&#xff08;2&#xff09;修改频率 analogWriteFreq&#xff08;3&#xff09;调节分辨率二、使用 analogWrite实现…

思腾合力深思系列 | 四款高性能 AI 服务器

深思系列 AI 服务器涵盖多种 CPU 平台&#xff0c;支持按客户需求预装 OS、驱动、DL 框架、常用 DL 库&#xff0c;节省您大量的前期调试时间&#xff0c;开机即用。 一个简单的任务&#xff0c;若想要在 AI 的脑中形成清晰的思路&#xff0c;需要大量的实验和练习。从 AI 训练…

05-CSS

今日目标能够说出 为什么要用定位能够说出 定位的 4 种分类能够说出 4 种定位各自的特点能够说出 为什么常用子绝父相布局能够写出 淘宝轮播图布局能够说出 显示隐藏的 3 种方式以及区别1. 定位(position) 介绍1.1 为什么使用定位我们先来看一个效果&#xff0c;同时思考一下用…

ctfshow_crypto_妈呀完了writeup

目录一、题目原题二、解题步骤1.去掉01串中的空格2.把01二进制串转换成十进制数3.将十进制整数转换成bytes三、后记一、题目原题 题目给了一串01和一个png图片&#xff0c;打开看了提示说“图文无关”&#xff1a; 图片附件如下&#xff1a; 二、解题步骤 1.去掉01串中的空…

3·8 妇女节特别策划 | 对话开源社里的“半边天”:多彩的她们,有别样的力量~...

三八妇女节Womens Day< 2023/03/08 >01职场女性 陈阳开源社理事长、微软云计算机与人工智能事业部首席产品经理一句话介绍自己&#xff1a;开源社区中的二进制女性向上滑动阅览采访Q1&#xff1a;能介绍一下自己目前正在做的职业或者项目嘛&#xff1f;白天在微软云计算和…

Oracle调优日记

Oracle调优日记前言前置知识联表查询Inner Joinleft joinright join环境背景描述问题展示最初代码问题解决过程优化一优化二优化三接口测试检查数据库连接总结前言 很难想想会在600条数据和4万条数据的两张表联表查询的的情况下&#xff0c;查询花了10多s。这里记录一下排查过…

PMP考试是什么?介绍+资料分享

我来介绍一下PMP&#xff1a; PMP考试是由PMI组织和出题&#xff0c;严格评估项目管理人员知识技能是否具有高品质的资格认证考试。 1999年&#xff0c;PMP考试在所有认证考试中第一个获得ISO9001国际质量认证,从而成为全球权威的认证考试之一。下载PMP备考资料可看封面或在文…

二叉树经典14题——初学二叉树必会的简单题

此篇皆为leetcode、牛客中的简单题型和二叉树基础操作&#xff0c;无需做过多讲解&#xff0c;仅付最优解。有需要的小伙伴直接私信我~ 目录 1.二叉树的节点个数 2.二叉树叶子节点个数 3.二叉树第K层节点个数 4.查找值为X的节点 5.leetcode——二叉树的最大深度 6.leetc…

Spark(5):RDD概述

目录 0. 相关文章链接 1. 什么是RDD 2. RDD核心属性 3. 执行原理 0. 相关文章链接 Spark文章汇总 1. 什么是RDD RDD&#xff08;Resilient Distributed Dataset&#xff09;叫做弹性分布式数据集&#xff0c;是 Spark 中最基本的数据处理模型。代码中是一个抽象类&#x…

淘宝widget链路方案总结

目前widget生态已经做了大量的基建工作,同时在widget生态的演进过程中我们发现如何匹配用户的偏好一直以来是一个挑战工作&#xff0c;本文介绍了widget的整体链路。业务背景▐ widget介绍2020年底iOS推出了新版widget之后引起了一些声浪&#xff0c;但仍然很多苹果用户并不了…

三、基本的select语句

一、SQL概述 1、SQL背景知识 2、SQL语言排行 3、SQL分类 SQL语言在功能上主要分为如下3大类&#xff1a; DDL&#xff08;Data Definition Languages、数据定义语言&#xff09;&#xff0c;这些语句定义数据库、表、视图、索引等数据库对象&#xff0c;还可以用来创建、删除…

MacOS + AndroidSDK + appium + 真手机(Android系统)环境搭建

需要的环境&#xff1a;Node.js version: ^14.17.0 || ^16.13.0 || >18.0.0NPM version > 8Java8python3Android SDK (通过Andriod Studio 安装)Appium client desktop (v1.19.1)install brew/bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/ma…

Docker启动问题docker is starting…

环境window 10 家庭最新版直接上官网安装的 Docker DeskTop问题启动应用后setting打开一直转圈圈&#xff1b;主界面一直显示 docker is starting…解决方案3.1 先确定hyper-v是否开启搜hyper-v&#xff0c;点击启动或关闭Windows功能如下,选中Hyper-V服务3.2 进入任务管理期&a…

Hive 常用函数

Hive 常用函数一、常用内置函数1、空字段赋值2、CASE WHEN THEN ELSE END3、行转列4、列转行5、窗口函数&#xff08;开窗函数&#xff09;6、Rank二、常用日期函数三、常用取整函数四、常用字符串操作函数五、集合操作一、常用内置函数 查看系统自带的函数show functions;显示…

【AcWing】学了一坤时才明白的一道题

&#x1f386;音乐分享 &#xff08;点击链接可以听哦&#xff09; The Right Path - Thomas Greenberg 这道题小吉花了一坤时才弄明白&#xff0c;虽然花的时间有点长 但是至少是明白了 &#x1f60e;&#x1f60e;&#x1f60e;&#x1f60e;&#x1f60e;&#x1f60e; …

Java程序占用CPU过高排查

使用 top 命令查看高CPU进程&#xff0c;执行命令后可以按 1 键查看各CPU 内核负载情况。CPU使用率主要看us、sy两个指标。假设 10760 是一个高CPU的进程。使用 top -H -p 查看 10760 的线程信息top -H -p 10760TIME列就是各个Java线程耗费的CPU时间。以线程ID 10952的线程为例…

Msyql聚簇索引和非聚簇索引

前提MySQL索引一直是面试中的常客&#xff0c;一提起索引&#xff0c;很多人都能答出来我知道Hash索引和B树索引&#xff0c;Hash是比较简单的&#xff0c;那么B树索引就有点复杂了。在创建表的时候&#xff0c;我们可以看到引擎有MyISAM , InnoDB等等&#xff0c;这两种是我们…

ARM uboot 的移植3 -从 uboot 官方标准uboot开始移植

一、选择合适的官方原版 uboot 1、官方原版 uboot 的版本 (1) 版本号。刚开始是 1.3.4 样式&#xff0c;后来变成 2009.08 样式。 (2) 新版和旧版的差别。uboot 的架构很早就定下来了&#xff0c;然后里面普遍公用的东西&#xff08;common 目录下、drivers 目录下、fs 目录…

CSS快速入门

文章目录一、CSS是什么&#xff1f;语法规范引入方式二、CSS选择器标签选择器类选择器ID选择器通配符选择器后代选择器子选择器并集选择器伪类选择器三、常见元素属性字体属性文本属性背景属性圆角矩形元素的显示默认块级与行级元素盒子模式去除浏览器默认样式弹性布局一、CSS是…

JUC并发编程共享模型之管程(三)(中)

4.5Monitor概念 Java 对象头 以 32 位虚拟机为例&#xff08;在32位虚拟机中&#xff0c;1个机器码等于4字节&#xff0c;也就是32bit&#xff0c;在64位虚拟机中&#xff0c;1个机器码是8个字节&#xff0c;也就是64bit&#xff09; 普通对象 数组对象 其中Mark Word 结构为…