【Vue面试题九】、Vue中给对象添加新属性界面不刷新?

文章底部有个人公众号:热爱技术的小郑。主要分享开发知识、学习资料、毕业设计指导等。有兴趣的可以关注一下。为何分享? 踩过的坑没必要让别人在再踩,自己复盘也能加深记忆。利己利人、所谓双赢。

面试官:动态给vue的data添加一个新的属性时会发生什么?怎样解决?

在这里插入图片描述

一、直接添加属性的问题

我们从一个例子开始

定义一个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实现数据响应式的,直接动态添加新属性仍可以实现数据响应式

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C# OpenCvSharp Yolov8 Pose 姿态识别

效果 项目 代码 using OpenCvSharp; using OpenCvSharp.Dnn; using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms;namespace OpenC…

【数据结构--八大排序】之希尔排序

&#x1f490; &#x1f338; &#x1f337; &#x1f340; &#x1f339; &#x1f33b; &#x1f33a; &#x1f341; &#x1f343; &#x1f342; &#x1f33f; &#x1f344;&#x1f35d; &#x1f35b; &#x1f364; &#x1f4c3;个人主页 &#xff1a;阿然成长日记 …

C++简单上手helloworld 以及 vscode找不到文件的可能性原因

helloworld #include <iostream>int main() {std::cout << "hello world!" << std::endl;return 0; }输入输出小功能 #include <iostream> using namespace std; /* *主函数 *输出一条语句 */int main() {// 输出一条语句cout << &q…

javaWeb宠物领养系统

一、引言 1.1 系统背景 计算机网络的发展&#xff0c;促进了社会各行业的进步&#xff0c;带来了经济快速增长。管理员通过流浪宠物的信息&#xff0c;在平台上和领养人进行实时的交流&#xff0c;达成领养协议。用户登录后&#xff0c;把想要领养的宠物向本平台发起申请&…

Python3操作Redis最新版|CRUD基本操作(保姆级)

Python3中类的高级语法及实战 Python3(基础|高级)语法实战(|多线程|多进程|线程池|进程池技术)|多线程安全问题解决方案 Python3数据科学包系列(一):数据分析实战 Python3数据科学包系列(二):数据分析实战 Python3数据科学包系列(三):数据分析实战 Win11查看安装的Python路…

【SpringBoot】| Thymeleaf 模板引擎

目录 Thymeleaf 模板引擎 1. 第一个例子 2. 表达式 ①标准变量表达式 ②选择变量表达式&#xff08;星号变量表达式&#xff09; ③链接表达式&#xff08;URL表达式&#xff09; 3. Thymeleaf的属性 ①th:action ②th:method ③th:href ④th:src ⑤th:text ⑥th:…

Swift SwiftUI CoreData 过滤数据 2

预览 Code import SwiftUI import CoreDatastruct HomeSearchView: View {Environment(\.dismiss) var dismissState private var search_value ""FetchRequest(entity: Bill.entity(),sortDescriptors: [NSSortDescriptor(keyPath: \Bill.c_at, ascending: false)…

Golang 程序漏洞检测利器 govulncheck(三):github 集成方法

上一篇文章详细介绍了 Golang 程序漏洞扫描工具 govulncheck 使用的漏洞数据库&#xff08;Go vulnerability database&#xff09;&#xff0c;本文详细讲解下 Github 项目如何使用 govulncheck。 govulncheck 为 Golang 开发者提供了一种准确可靠的方式来了解程序中可能存在…

Kafka 高可用

正文 一、高可用的由来 1.1 为何需要Replication 在Kafka在0.8以前的版本中&#xff0c;是没有Replication的&#xff0c;一旦某一个Broker宕机&#xff0c;则其上所有的Partition数据都不可被消费&#xff0c;这与Kafka数据持久性及Delivery Guarantee的设计目标相悖。同时Pr…

MySQL增删查改(进阶1)

一、数据库约束 约束&#xff1a;按照一定条件进行规范的做事&#xff1b; 表定义的时候&#xff0c;某些字段保存的数据需要按照一定的约束条件&#xff1b; 1.null约束 字段null&#xff1a;该字段可以为空&#xff1b;not null&#xff1a;该字段不能为空不指定的话就是…

bigemap在林业勘测规划设计行业的一些应用

选择Bigemap的原因&#xff1a; 主要注重影像的时效性&#xff0c;软件的影像时效性比其他的更新快&#xff0c;更清晰。 使用场景&#xff1a; 1.林业督查&#xff0c;主要是根据国家下发的图斑&#xff0c;结合测绘局的影像以及bigemap的较新影像对比去年和今年的林地变化。…

Kafka实战案例

kafka系统的生成&#xff0c;自顶向下 1. kafaka发送消息 1.1 是最初始外部调用kafaka的地方1.6 是最初调用kafaka的函数。中间是对kafaka的构建 1.1 向Kafka发送一条发布视频的message 在videoHandler的发布视频逻辑中&#xff0c;向Kafka发送一条发布视频的mq&#xff0c…

【轻松玩转MacOS】常用软件篇

引言 在本篇文章中&#xff0c;我将介绍如何安装和使用一些常用的软件&#xff0c;如Safari浏览器、邮件、日历、地图等。让我们一起来看看吧&#xff01; 一、Safari浏览器 Safari是MacOS自带的浏览器&#xff0c;具有简洁、快速、安全的特点。 以下是一些Safari浏览器的使…

Zabbix自定义脚本监控MySQL数据库

一、MySQL数据库配置 1.1 创建Mysql数据库用户 [rootmysql ~]# mysql -uroot -p create user zabbix127.0.0.1 identified by 123456; flush privileges; 1.2 添加用户密码到mysql client的配置文件中 [rootmysql ~]# vim /etc/my.cnf.d/client.cnf [client] host127.0.0.1 u…

vue模版语法-{{}}/v-text/v-html/v-once

一、{{}}双括号&#xff1a;用于文本渲染 1、 {{变量名}}:data中返回对象的变量名 2、{{js表达式}}:可以直接进行js表达式处理 3、注意&#xff1a;双大括号中不要写等式书写 二、v-text 指令&#xff0c;用于文本渲染 1、为了解决双大括号渲染数据出现闪烁问题 三、v-cloak …

Qt中的基础数据类型

1.基础类型 因为Qt是一个C++ 框架, 因此C++中所有的语法和数据类型在Qt中都是被支持的, 但是Qt中也定义了一些属于自己的数据类型, 下边给大家介绍一下这些基础的数类型 QT基本数据类型定义在#include <QtGlobal> 中,QT基本数据类型有: 类型名称注释备注qint8signed ch…

盒子模型的基础

盒子模型 边框&#xff08;border&#xff09; border可以设置元素的边框&#xff0c;边框分成三部分&#xff0c;边框的&#xff08;粗细&#xff09;边框的样式&#xff0c;边框的颜色 <style>div {width: 100px;height: 100px;border-width: 200;border-style: 边框…

【面试HOT100】哈希双指针滑动窗口

系列综述&#xff1a; &#x1f49e;目的&#xff1a;本系列是个人整理为了秋招面试的&#xff0c;整理期间苛求每个知识点&#xff0c;平衡理解简易度与深入程度。 &#x1f970;来源&#xff1a;材料主要源于LeetCodeHot100进行的&#xff0c;每个知识点的修正和深入主要参考…

openGauss学习笔记-92 openGauss 数据库管理-内存优化表MOT管理-内存表特性-使用MOT-MOT使用MOT SQL覆盖和限制

文章目录 openGauss学习笔记-92 openGauss 数据库管理-内存优化表MOT管理-内存表特性-使用MOT-MOT使用MOT SQL覆盖和限制92.1 不支持的特性92.2 MOT限制92.3 不支持的DDL操作92.4 不支持的数据类型92.5 不支持的索引DDL和索引92.6 不支持的DML92.7 不支持的JIT功能&#xff08;…

自然语言处理的分类

动动发财的小手&#xff0c;点个赞吧&#xff01; 简介 作为理解、生成和处理自然语言文本的有效方法&#xff0c;自然语言处理&#xff08;NLP&#xff09;的研究近年来呈现出快速传播和广泛采用。鉴于 NLP 的快速发展&#xff0c;获得该领域的概述并对其进行维护是很困难的。…