vue中修改数组内容视图没有发生更新问题源码解析

【ARM Trace32(劳特巴赫) 使用介绍 1.3 - ARM 系统调试中常见的挑战】 每一个独立的gust os或者一个OS 内部里面美格独立的进程它使用虚拟地址是可能是重叠的,比如linux中每个用户进程它的运行地址(虚拟地址)都是0x0,这时如果想去同时调试所有进程,那么必须要有个办法把这些进程区分开来,trace32 就在虚拟地址前面加前缀的方法,这个前缀称为space id, 这个space id 实际上就是processor id或者是task id, 这样就可以把一个os内部的不同的进程区分开来。如果工具和内核中的连接是可以建立起来的,那么接下来就是调试工具使用的问题了。 阅读详情

改变数组长度无法触发视图更新

在vue中,我们可能会有这种情况,修改了数组的长度,但是视图没有发生更新

<template>
  <div id="app">
      <div v-for="(item,index) in arr" :key="index">
        {{index}}:{{item}}
      </div>
      <button @click="click">btn</button>
  </div>
</template>
export default {
  name: 'app',
  data(){
    return{
      arr:[1,2,3,4,5]
    }
  },
  methods:{
    click:function(){
      this.arr.length=6
      console.log('this.arr: ', this.arr)
    }
  }
}

在这里插入图片描述
可以看到数组的长度已经变成了6,最后一个为empty,但是却没触发视图的更新
在这里插入图片描述

而当我们在点击方法后面添加一个push操作,就会触发视图的更新

export default {
  name: 'app',
  data(){
    return{
      arr:[1,2,3,4,5]
    }
  },
  methods:{
    click:function(){
      this.arr.length=6
      console.log('this.arr: ', this.arr)
      this.arr.push(7)
      console.log('this.arr: ', this.arr)
    }
  }
}

在这里插入图片描述

可以看到,视图发生了更新,this.arr.length=6触发的数组变化

我们试着不用push,直接给arr上某个成员变量重新赋值

export default {
  name: 'app',
  data(){
    return{
      arr:[1,2,3,4,5]
    }
  },
  methods:{
    click:function(){
      this.arr.length=6
      console.log('this.arr: ', this.arr)
      this.arr[0] = 2
      console.log('this.arr: ', this.arr)
    }
  }
}

点击发现视图也是没有发现变化

为什么使用push,数组会发生变化,但是改变长度和数组成员就无效呢,我们可以从源码去进行解析

源码解析

我们知道,在vue里面,其核心双向绑定的实现,是通过Object.defineProperty()(在vue3中使用了proxy)来劫持对象的,但Object.defineProperty()无法劫持数组成员的变化,而实际上,我们在使用vue的时候,当我们通过push,splice,pop等方法去修改数组的时候,是会触发响应式更新的,那么vue是怎么做到的呢

实际上,vue重写了这些方法

vue/src/core/observer/array.js

/*
 * not type checking this file because flow doesn't play well with
 * dynamically accessing methods on Array prototype
 */

import { def } from '../util/index'

const arrayProto = Array.prototype
export const arrayMethods = Object.create(arrayProto)

const methodsToPatch = [ // 将要重写的方法放在一个数组中
  'push',
  'pop',
  'shift',
  'unshift',
  'splice',
  'sort',
  'reverse'
]

/**
 * Intercept mutating methods and emit events
 */
methodsToPatch.forEach(function (method) {
  // cache original method
  const original = arrayProto[method] // 得到原来的方法
  def(arrayMethods, method, function mutator (...args) { // 将重写的方法定义到arrayMethods上,mutator就是重写的方法
    const result = original.apply(this, args) // 执行原方法得到结果
    const ob = this.__ob__
    let inserted
    switch (method) {
      case 'push':
      case 'unshift':
        inserted = args
        break
      case 'splice':
        inserted = args.slice(2)
        break
    }
    if (inserted) ob.observeArray(inserted)
    // notify change
    ob.dep.notify() // 发布订阅,触发视图更新
    return result
  })
})

将这些方法重写到arrayMethods上之后,我们还需要将data上的数组对应的方法改成我们定义的方法,所以需要在Ovserver中对数组的监听做额外的处理
vue/src/core/observer/index.js

import { arrayMethods } from './array' // 引入在array中我们重定义的方法
export class Observer {
  value: any;
  dep: Dep;
  vmCount: number; // number of vms that have this object as root $data

  constructor (value: any) {
    this.value = value
    this.dep = new Dep()
    this.vmCount = 0
    def(value, '__ob__', this)
    if (Array.isArray(value)) { // 判断为数组
      if (hasProto) { // 如果有__prop__,则将数组的__prop__指向arrayMethods
        protoAugment(value, arrayMethods)
      } else {
        copyAugment(value, arrayMethods, arrayKeys) // 否则直接把重写的方法写在数组上
      }
      this.observeArray(value) // 监听数组里的每个成员
    } else {
      this.walk(value)
    }
  }
  // ...
  observeArray (items: Array<any>) {
    for (let i = 0, l = items.length; i < l; i++) {
      observe(items[i])
    }
  }
}
// ...
function protoAugment (target, src: Object) {
  /* eslint-disable no-proto */
  target.__proto__ = src
  /* eslint-enable no-proto */
}

function copyAugment (target: Object, src: Object, keys: Array<string>) {
  for (let i = 0, l = keys.length; i < l; i++) {
    const key = keys[i]
    def(target, key, src[key])
  }
}

回到问题

现在我们可以知道,为什么用push可以,而直接修改length和数组成员不行了

vue对于数组的处理,是将push,pop,splice等多个数组操作的方法重写,在调用这些方法的时候就去触发视图的更新

所以就会出现这样的情况
当我们调用这个方法的时候,视图没有更新

click:function(){
    this.arr.length=6
    console.log('this.arr: ', this.arr)
}

但是当我们调用push,即使我们没有push进任何东西,依然会引起视图的更新

click:function(){
    this.arr.length=6
    console.log('this.arr: ', this.arr)
    this.arr.push()
    console.log('this.arr: ', this.arr)
}

在这里插入图片描述
所以如果你修改数组后,视图没有发生更新,在处理的函数后面加入一行

this.arr.push()

如果视图成功发生更新,那就说明你是直接去修改了数组的成员或者操作它的属性了

别把 ABAP 时间戳当数字算:TIMESTAMP / TIMESTAMPL 的语义、正确用法与项目级避坑指南 ABAP时间戳使用指南与常见陷阱 摘要:ABAP中的时间戳(TIMESTAMP/TIMESTAMPL)本质是UTC时间的数字表示,而非累计秒数。正确用法包括:直接比较时间戳顺序、使用CONVERT TIME STAMP进行时区转换、通过CL_ABAP_TSTMP计算时间差。关键注意事项:绝对不要对时间戳本身进行数学运算,否则会导致非法时间值。实际项目中需特别注意SAP Gateway的ETag处理、跨时区系统集成和CDS视图中的时间戳使用场景,避免将本地时间误存为UTC时间戳或在云迁移时产生时区问题。(14 阅读详情

相关推荐

数据结构实验1 集合的交、并、差

姓名:Far_Rainbow 学号: 202505000X 专业: 软件工程 年级:2020级 实验名称:实验1 集合的交、并、差 实验内容: (1)实验目的 通过该实验,让学生复习巩固C语言中的循环结构、循环控制条件、分支结构和数组/链表、函数的调用等有关内容,体会到用数组存储集合时,需要记录集合元素的个数,否则输出结果会出现数据越界现象。 (2)实验内容 通过键盘,分别输入两个数据元素类型为正整数的集合A和B,以负数输入为结束条件,输出两个集合的交、并、差。 (3)实验要求 从程序完善性上考虑,集合元

Far_Rainbow的博客 2176

vue开发中,数据更新,但视图不刷新

我们在开发过程中会碰到数据更新,但是视图并未改变的情况,情况如下:第一种:动态给对象新增属性或者删除属性是不会触发视图刷新的,Vue识别不到;第二种:通过数组下标修改数组中的元素或者手动修改数组的长度,Vue识别不到;**解决方法1:静默刷新(使用v-if的特性) 在修改值之后将元素销毁,然后在修改后的下一次DOM渲染完成时再显示出来,这样就会触发组件重新加载data的数据进行渲染,data中被修改的数据才是最新的。 解决方法2:Vue.$set(官方推荐) 使用这个api修改的数据会为其添加响应式gett

Quentin0823的博客 3万+

VulnHub--mrrobot

Vulnhub靶场--Mr robot 靶机

记录笔记 1093

vue数据更新但不改变视图,解决办法?

第一种:动态给对象新增属性或者删除属性是不会触发视图刷新的; 第二种:通过数组下标修改数组中的元素或者手动修改数组的长度;

smallmww的博客 5768

手把手教你用Apple Developer App完成苹果开发者账号注册(含证件验证失败解决方案)

本文详细指导如何通过Apple Developer App完成苹果开发者账号注册,特别针对证件验证失败问题提供解决方案。从准备工作到注册流程,再到验证失败的处理方法,帮助开发者顺利完成注册,避免常见错误。

moss5的博客 1156

一、数学建模层次分析法(AHP)【清风数学建模个人笔记】

层次分析法: 层次分析法主要用于解决评价类问题(例如:选择哪种方案更好、哪位员工、运动员等表现得更优秀) 评价类问题: 分析问题得出评判问题的子标,分别给不同子标赋予权重(权重和要为1) ...

m0_58882109的博客 1万+

(详解错误情况,及解决方法)Vue 数据更新了但页面没有更新的情况

(详解错误情况,及解决方法)Vue 数据更新了但页面没有更新的情况

m0_55333789的博客 1万+

【车载以太网】ATU(Address Translation Unit / Address Table Unit)

【车载以太网】ATU(Address Translation Unit / Address Table Unit)

天赐好车的博客 150

Vue数据更新页面却没有更新的几种情况以及解决方法

情况一:Vue无法检测实例被创建时不存在于data中的变量 原因:由于 Vue 会在初始化实例时对 data中的数据执行 getter/setter 转化,所以 变量必须在 data 对象上存在才能让 Vue 将它转换为响应式的。 例如: 1 2 3 4 5 new Vue({ data:{}, template: '<div>{{message}}&l...

jyf_568的博客 7214

10天冲刺国自然基金!用这套实战AI提示词指令教程,助你中标率翻倍!亲测DeepSeek和ChatGPT不好用

虽然以上国自然提示词指令经过反复实测,但并不是万能无脑帮你搞定所有,大模型AI的特性是你专业领域能力越强,它的智商表现就会更加强大,通过以上提示词教程的使用,大大提升中标概率是肯定的。还有就是大模型的使用上,不是市面上大家都说好的就一定适用,目前来看,Gemini和Claude的两个模型是非常适合国自然本子的修改的。在使用大模型进行国自然本子撰写修改时,首先是角色的设定,然后是目标和背景的描述,好用的提示词指令都是要经过无数次的实测,比对输出结果后又反复调整,达到最佳的效果状态的提示词指令。

智能AI让学术科研更容易 1244

mindie部署qwen3-8b

2. 确认目录文件权限是否如下所示,若存在不匹配项,则参考以下命令修改权限。否则要stop容器之后重新start,重新从《以下是在容器中的操作》开始操作。ctrl +d 让命令停止之后,需要等待一段事件让其释放,否则还会有占用。1. 若安装路径为默认路径,执行如下命令,进入MindIE安装目录。# 配置CANN环境,默认安装在/usr/local目录下。3. 运行以下命令初始化各组件环境变量,并开启日志打印。如果报错,可能有些线程没法去除,删除容器重新操作。# 配置模型仓环境变量。以下是在容器中的操作。

andeyeluguo的博客 1035

vue数据更新但视图(DOM)不刷新解决办法

对此有什么疑问 或者 其它前端面临的问题都可以来欢迎评论 在下知道的定会帮你回答希望能够帮到你 (#^.^#)第二种:vue.$set(要操作的对象或数组, 对象key/索引, 修改后的值)第三种: vue.$forceUpdate()第一种:强制更新dom; vue数据更新但视图不刷新解决办法

weixin_49315886的博客 1万+

基于Simulink的六旋翼无人机动力分配仿真建模示例

六旋翼无人机概述特点:高冗余度、增强的负载能力和更好的故障容忍性。关键组件电机与螺旋桨:提供升力和推力。电调(ESC):控制电机转速。IMU(惯性测量单元):包括加速度计和陀螺仪,用于姿态估计。飞控板:处理传感器数据并生成控制信号。应用场景:航拍摄影、农业监测、物流配送等。仿真目标搭建一个简化的六旋翼无人机动力分配模型,涵盖电机驱动、姿态控制及位置控制过程。分析不同条件下的性能指标(如响应时间、稳定性等),并探讨六旋翼无人机的设计优化。

xiaoheshang_123的博客 484

Vue中修改了数组数值,视图没有更新?

开篇闲扯 在人类求知的路上,会形成对求知的不同的态度,比如好读书,不求甚解;又例如要知其然知其所以然,追本溯源等等,人类在满足自己好奇心的同时,掺杂着复杂的人性。前者“懒惰”,后者“贪婪”。人类总能逻辑自洽的自圆其说。技术的变化很快,新东西更替不断,让人眼花缭乱。一个新的框架出来,大家都会在各种社区或者谈论组表示 学不动.gif 。了解背后的原理就显得特别重要。最近在看网络协议和浏览器方面的东西。浅尝辄止的了解编译原理方面的知识,所以今天就分享下vue中视图跟数据的关系的一个知识点(皮.png)。 进入正题

前端慢报 2838

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

3.为什么我的vue数据修改后视图未更新,梳理Vue2和Vue3中常见的数据不更新场景

Vue数据不更新问题的核心在于响应式机制的实现。Vue2受限于Object.defineProperty,需通过辅助方法(如$set)弥补不足;而Vue3通过Proxy提供了更完善的响应式支持。无论是Vue2还是Vue3,理解其原理并遵循“数据驱动视图”的原则,配合最佳实践,都能有效避免视图更新异常。

qq_1401820561的博客 2681

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

vue数组刷新_vue 数组更新视图不更新的问题

0. 解决方案1.当你利用索引直接设置一个项时,例如:vm.items[indexOfItem] = newValue2.当你修改数组的长度时,例如:vm.items.length = newLength对于第一种情况,可以使用:Vue.set(example1.items, indexOfItem, newValue);而对于第二种情况,可以使用 vm.items.splice(newLengt...

weixin_34847632的博客 1119

vue 修改对象的值视图没有发生改变_从源码解惑,为什么明明修改了数据视图却不更新__Vue.js...

问题描述在使用Vue日常工作开发中,偶尔会遇到这种问题,明明我已经修改了数据,但是视图却没有更新。比如下面这些骚操作:直接在对象上新增属性直接删除对象属性通过角标[]直接修改数组的某一项直接修改数组的length问题分析想要了解为什么上面这些写法不会触发视图更新,只需要搞清楚在vue中是如何对数据进行响应式处理的。知道了vue的数据响应机制,那么跳出机制的写法自然就不能触发视图更新了。在vue中,...

weixin_32310195的博客 903

Vue响应式数组方法深度解析

Vue响应式数组方法深度解析

嗨,欢迎来到我的 优快云 博客小天地!一名深耕多年的技术发烧友。在这里,我将把日常工作中积累的宝贵经验,从复杂架构设计的精妙之处,到代码优化的实战技巧,毫无保留地分享给大家。 4510

sortable.js——Vue 数据更新问题

从一个 bug 说起 在一个需求中,我需要实现一个拖拽的功能,其中我使用了 sortable.js 去实现,但我发现我拖拽之后的数据并没有渲染在页面上。 简而言之,举个例子,原先的数组是 [1,2,3,4],拖拽之后,变成了 [4,1,2,3],但在视图上并没有显现,这不经让我疑惑不解,开始了以下问题的探索,在此记录一下 Vue 的数组更新问题 看到以上问题,你肯定会认为我处理数组的方式不对,毕竟...

weixin_33712881的博客 3989

从源码中分析为什么vue2中直接对数组的元素进行赋值无法触发页面的更新

从源码中分析为什么vue2中直接对数组的元素进行赋值无法触发页面的更新场景代码问题描述原因分析 场景代码 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=devi

小何程序员的博客 2946

js怎么实现数组里的数据相加_从源码中学Vue(六)「解密」为什么操作数组的方法也会触发视图更新...

欢迎来到我的《从源码中学Vue》专题系列文章,更多精彩内容持续更新中,欢迎关注 :)上一章节我大概分析了下在Vue中的 Watcher、Observer、Dep三者的关系,以及如何检测数据变化去更新视图的,以及通过源码分析了vue在初始化的时候是如何响应模板数据。本章目标Object.defineProperty存在的问题为什么在我们操作数组的时候可以实现视图更新vue中数组劫持仍然存在的问题Ob...

weixin_32831351的博客 683

vue2 js中数组数据修改后页面数据没有响应更新的原因&处理方法

数组监听的关键是 “让修改行为进入 Vue2 的响应式链路优先用7 个变异方法(push/pop/splice 等),Vue 自动监听;若需改索引 / 长度,用this.$set或splice手动触发;若用 filter/map 等非变异方法,需将新数组重新赋值给原变量(更新引用)。本质是 Vue2 对数组的响应式做了 “性能与功能的平衡”—— 不劫持单个元素(避免大数组性能损耗),而是通过 “方法重写 + 手动 API” 覆盖主流修改场景。

weixin_43729692的博客 924

Vue 源码之Vue视图更新原理【一】

Vue 视图更新原理

weixin_42524603的博客 1884

浅探 Vue 2为什么没有数组下标响应式

Vue 的双向数据绑定,使得修改数据后,视图就会跟着发生更新,比如对数组进行增加元素、切割等操作。然而直接通过下标修改数组内容后,视图却不发生变化。那么,在保留原有的数组响应方式下,为什么 Vue 不增加对数组下标的响应式监听呢? arr[index] = val 不是响应式的 在 Vue 官网的列表渲染 — Vue.js中,有强调 Vue不能直接检测通过数组下标改变值的变化,需要通过数组更新检测来实现。 <template> <div> <sp...

Vera_Gao的博客 1720

从Vue源码来看数组操作

文章目录文章风格学习目标学习过程不用forceUpdate调用forceUpdate一些会自动触发视图更新的办法学习总结 文章风格 基于研发者心理talk is cheap, show me the code原则,文章可能会涉及大量代码。 学习目标 相信很多人写Vue的时候,如果碰到了这样的情况(本意想要视图更新,但是视图却没有更新的时候),往往会不管三七二十一,直接一波$forceupdate完事,但是再读源码的时候,你就会发现为什么视图没有自动更新了。 学习过程 不用forceUpdate 比

程序员三木的博客 813

vue源码(十三) 数组下标改变值的响应式误区以及实现

前言 相信大家都知道,在vue2.0x中,使用数组下标改变值时,是不会触发响应式的 以下来自:Vue官方文档 Vue 不能检测以下数组的变动: 当你利用索引直接设置一个数组项时,例如:vm.items[indexOfItem] = newValue 当你修改数组的长度时,例如:vm.items.length = newLength 但是其实还是有特殊情况的,让我们来分析分析 正常情况 让我们看看,使用数组下标直接改变数组元素的值,是否会响应式变化(按照官方文档是不可行的) <div id="a

小鹿的博客 6283

vue获取data中数组的value值_控制台修改vue组件中data对象里的数组意外失效

摘要:最近在学习Vue.js,其语法很像angularjs。然后在学习过程中遇到一些奇怪的事情,比如这篇提到的:修改data对象里面的数组,有的成功有的意外失效......一、发现最近在看Vue.js,然后发现data对象里面的属性并非都可以通过控制台来更新!按照官方的说法:每个 Vue实例都会代理其 data对象里所有的属性,注意只有这些被代理的属性是响应的......配图一张:然后艺灵就按照此...

weixin_33521678的博客 3116
上一篇: Electron开发笔记----前端小白开发桌面应用之路(四)桌面应用中的跳转
下一篇: 前端面试手撕代码小集合(仍在补充中)
前端小黑
博客等级 码龄9年 148粉丝 222原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值