4. 数组更新检测

news2024/11/26 11:55:26

4.1 v-for更新监测

当v-for遍历的目标结构改变, Vue触发v-for的更新

情况1: 数组翻转

情况2: 数组截取

情况3: 更新值

口诀:

  • 数组变更方法, 就会导致v-for更新, 页面更新

  • 数组非变更方法, 返回新数组, 就不会导致v-for更新, 可采用覆盖数组或this.$set()

这些方法会触发数组改变, v-for会监测到并更新页面

  • push()

  • pop()

  • shift()

  • unshift()

  • splice()

  • sort()

  • reverse()

代码演示:

<template>
    <div>
        <ul>
            <li v-for="item in arr" :key="item">
                {{item}}
            </li>
        </ul>
        <button @click="changarr">改变数组</button>
    </div>
</template>
<script>
export default {
    data(){
        return{
            arr:[1,3,5,7,9]
        }
    },
   methods:{
    changarr:function(){
        //通过索引添加数组
      //  this.arr[5]=10;
       // - `push() 给数组末尾添加元素
        //this.arr.push(7,8,9);

        // - `pop()`删除掉数组末尾的元素
        //this.arr.pop()

        // - `shift()` 给数组第一位进行删除
        //this.arr.shift()

        // - `unshift()` 给数组首位开始添加元素
        //this.arr.unshift(0,9,8)
        // - `splice()` 删除元素,插入元素,替换元素
        //说明:第一个元素表示开始插入或者开始删除的元素位置下标
        //删除元素
        //第二个参数表示要删除的几个元素(如果没有传,表示删除后面的所有的元素)
        //this.arr.splice(1,3)
        
        //插入元素
        //第二个参数,传入0 并且后面接上要插入的元素
       // this.arr.splice(1,0,3,2,1)

       //替换元素
       //第二个参数,表示我们替换几个元素 3表示3个元素 2,1,9表示替换的数据
       // this.arr.splice(1,3,2,1,9)
        // - `sort()` 排序
        this.arr.sort()
        // - `reverse()` 翻转
        this.arr.reverse()
    }
   }
}
</script>

这些方法不会触发v-for更新

  • slice()

  • filter()

  • concat()

<template>
    <div>
    <ul>
      <li v-for="(val, index) in arr" :key="index">
        {{ val }}
      </li>
    </ul>
    <button @click="revBtn">数组翻转</button>
    <button @click="sliceBtn">截取前3个</button>
    <button @click="updateBtn">更新第一个元素值</button>
    <button @click="filterUp">过滤条件数组</button>
  </div>
</template>
<script>
export default {
    data(){
    return {
      arr: [5, 3, 9, 2, 1],
      arr2:[2,5,6,7]
    }
  },
  methods: {
    revBtn(){
      // 1. 数组翻转可以让v-for更新
      this.arr.reverse()
    },
    sliceBtn(){
      // 2. 数组slice方法不会造成v-for更新
      // slice不会改变原始数组: 用于从已有的数组中选出选定的数组元素
       //this.arr.slice(0, 3)

      // 解决v-for更新 - 覆盖原始数组
      let newArr = this.arr.slice(0, 3)
      this.arr = newArr
    },
    updateBtn(){
      // 3. 更新某个值
     //  this.arr[0] = 1000;
     //concat 数组拼接
      let newArr=this.arr.concat(this.arr2)
      console.log(newArr)
    },
    filterUp(){
        //filter():过滤,可以过滤数组中的元素,还可以作为过滤器使用
        /*
        filter会返回一个新数组,新数组中包含符合条件的所有元素,
        arr.filter(function(val,index,arr))
        三个参数:
            val:当前数组值
            index:数组的下标
            arr:是数组
        */
        let newarr=this.arr.filter(function(val,index,arr){
            return val>3
        });
        console.log(newarr)

    }
  }
}
</script>

注意: vue 不能监测到数组里赋值的动作而更新,

如果需要请使用Vue.set() 或者this.$set(), 或者覆盖整个数组

改变原数组的方法才能让v-for更新

4.2 v-for就地更新

v-for 的默认行为会尝试原地修改元素而不是移动它们。

这种 虚拟DOM对比方式, 可以提高性能 - 但是还不够高

4.3 虚拟dom

.vue 文件中的 template 里写的标签, 都是模板,

都要被 vue 处理成虚拟 DOM 对象, 才会渲染显示到真实 DOM 页面上

  1. 内存中生成一样的虚拟DOM结构(==本质是个JS对象==)因为真实的DOM属性好几百个, 没办法快速的知道哪个属性改变了比如template里标签结构

<template>    
	<div id="box">       
	 <p class="my_p">123</p>    
	</div>
</template>

对应的虚拟DOM结构
const dom = {   
 type: 'div',  
  attributes: [{id: 'box'}],  
  children: {     
   type: 'p',      
  attributes: [{class: 'my_p'}],      
  text: '123'  
  }}

以后vue数据更新

  1. 生成新的虚拟DOM结构
  2. 和旧的虚拟DOM结构对比
  3. 利用diff算法, 找不不同, 只更新变化的部分(重绘/回流)到页面 - 也叫打补丁

==好处1: 提高了更新DOM的性能(不用把页面全删除重新渲染)==

==好处2: 虚拟DOM只包含必要的属性(没有真实DOM上百个属性)==

虚拟DOM保存在内存中, 只记录dom关键信息, 配合diff算法提高DOM更新的性能

在内存中比较差异, 然后给真实DOM打补丁更新上

 4.4 diff算法

vue用diff算法, 新虚拟dom, 和旧的虚拟dom比较

情况1: 根元素变了, 删除重建

旧虚拟DOM

<div id="box">
    <p class="my_p">123</p>
</div>

新虚拟DOM

<ul id="box">
    <li class="my_p">123</li>
</ul>

情况2: 根元素没变, 属性改变, ==元素复用==, 更新属性

旧虚拟DOM

<div id="box">    
    <p class="my_p">123</p>
</div>

新虚拟DOM

<div id="myBox" title="标题">
    <p class="my_p">123</p>
</div>

4.5 diff算法-key

情况3: 根元素没变, 子元素没变, 元素内容改变

无key - 就地更新

v-for不会移动DOM, 而是尝试复用, 就地更新,如果需要v-for移动DOM, 你需要用特殊 attribute key 来提供一个排序提示

<ul id="myUL">
    <li v-for="str in arr">
        {{ str }} 
        <input type="text">
    </li>
</ul>
<button @click="addFn">下标为1的位置新增一个</button>
export default {
    data(){
        return {
            arr: ["老大", "新来的", "老二", "老三"]
        }
    },
    methods: {
        addFn(){
            this.arr.splice(1, 0, '新来的')
        }
    }
};

旧 - 虚拟DOM结构 和 新 - 虚拟DOM结构 对比过程

 ==性能不高, 从第二个li往后都更新了==

代码演示:

<template>
    <div>
        <ul>
	<li v-for="item in person"><input type="checkbox" name="">
	{{item}}
	</li>
        </ul>
        <button @click="addperson">增加数据</button>
    </div>
</template>
<script>
export default {
    data(){
        return{
            person:["老大","老二","老三","老四"]
        }
    },methods:{
        addperson(){
            this.person.unshift("新来的")
        }
    }
}
</script>

有key - 值为索引

  • 还是就地更新

因为新旧虚拟DOM对比, key存在就复用此标签更新内容, 如果不存在就直接建立一个新的

<ul id="myUL">
    <li v-for="(str, index) in arr" :key="index">
        {{ str }} 
        <input type="text">
    </li>
</ul>
<button @click="addFn">下标为1的位置新增一个</button>
export default {
    data(){
        return {
            arr: ["老大", "新来的", "老二", "老三"]
        }
    },
    methods: {
        addFn(){
            this.arr.splice(1, 0, '新来的')
        }
    }
}

key为索引-图解过程 (又就地往后更新了)

  1. v-for先循环产生新的DOM结构, key是连续的, 和数据对应

  2. 然后比较新旧DOM结构, 找到区别, 打补丁到页面上最后补一个li, 然后从第二个往后, 都要更新内容

口诀: key的值有id用id, 没id用索引

有key - 值为id

key的值只能是唯一不重复的, 字符串或数值

v-for不会移动DOM, 而是尝试复用, 就地更新,如果需要v-for移动DOM, 你需要用特殊 attribute key 来提供一个排序提示

新DOM里数据的key存在, 去旧的虚拟DOM结构里找到key标记的标签, 复用标签

新DOM里数据的key存在, 去旧的虚拟DOM结构里没有找到key标签的标签, 创建

旧DOM结构的key, 在新的DOM结构里没有了, 则==移除key所在的标签==

<template>
  <div>
    <ul>
      <li v-for="obj in arr" :key="obj.id">
        {{ obj.name }}
        <input type="text">
      </li>
    </ul>
    <button @click="btn">下标1位置插入新来的</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      arr: [
        {
          name: '老大',
          id: 50
        },
        {
          name: '老二',
          id: 31
        },
        {
          name: '老三',
          id: 10
        }
      ],
    };
  },
  methods: {
    btn(){
      this.arr.splice(1, 0, {
        id: 19, 
        name: '新来的'
      })
    }
  }
};
</script>

<style>
</style>

图解效果:

不用key也不影响功能(就地更新), 添加key可以提高更新的性能

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

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

相关文章

基于深度学习的高精度鸽子检测识别系统(PyTorch+Pyside6+YOLOv5模型)

摘要&#xff1a;基于深度学习的高精度鸽子检测识别系统可用于日常生活中或野外来检测与定位鸽子目标&#xff0c;利用深度学习算法可实现图片、视频、摄像头等方式的鸽子目标检测识别&#xff0c;另外支持结果可视化与图片或视频检测结果的导出。本系统采用YOLOv5目标检测模型…

XSS注入——反射性XSS

xss注入的攻击步骤&#xff1a; 1.查找可能存在的注入点&#xff08;搜索框&#xff0c;留言板&#xff0c;注册&#xff09; 2.观察输出显示位置&#xff1a; html&#xff1a; 尖括号外部&#xff0c; 尖括号内部: 引号内部》闭合&#xff0…

Django | 基于pycharm的django配置52张全流程截图,红星给你一步一步的男妈妈式教学

演示版本&#xff1a;【windows系统】python3.10pycharm2023.1.2django4.2.2 &#xff08;本教程全程在虚拟机中演示&#xff0c;读者无需配置虚拟机&#xff0c;直接按教程安装即可&#xff09; 目录 1.搞到必要的安装包 2.事先准备 3.安装chrome浏览器&#xff08;也可以…

国产MCU-CW32F030开发学习--按键检测

国产MCU-CW32F030开发学习–按键检测 bsp_key 按键驱动程序用于扫描独立按键&#xff0c;具有软件滤波机制&#xff0c;采用 FIFO 机制保存键值。可以检测 如下事件&#xff1a; 按键按下。 按键弹起。 长按键。 长按时自动连发。 我们将按键驱动分为两个部分来介绍&#xff…

C语言学习笔记:顺序结构

✨博文作者&#xff1a;烟雨孤舟 &#x1f496; 喜欢的可以 点赞 收藏 关注哦~~ ✍️ 作者简介: 一个热爱大数据的学习者 ✍️ 笔记简介&#xff1a;作为大数据爱好者&#xff0c;以下是个人总结的学习笔记&#xff0c;如有错误&#xff0c;请多多指教&#xff01; 目录 程序与…

《面试1v1》Spring基础

&#x1f345; 作者简介&#xff1a;王哥&#xff0c;CSDN2022博客总榜Top100&#x1f3c6;、博客专家&#x1f4aa; &#x1f345; 技术交流&#xff1a;定期更新Java硬核干货&#xff0c;不定期送书活动 &#x1f345; 王哥多年工作总结&#xff1a;Java学习路线总结&#xf…

浅谈微前端

本文呢是我梳理的一个扫盲文&#xff0c;由于最近团队准备使用微前端对项目进行改造&#xff0c;所以我呢就先浅了解一下&#xff1a; 微前端到底是什么&#xff1f; 为什么要使用微前端&#xff1f; 都有哪些微前端方案&#xff1f; 微前端有什么不好的地方吗&#xff1f; 通过…

48 最佳实践-性能最佳实践-Guest-Idle-Haltpoll

文章目录 48 最佳实践-性能最佳实践-Guest-Idle-Haltpoll48.1 概述48.2 操作指导 48 最佳实践-性能最佳实践-Guest-Idle-Haltpoll 48.1 概述 为了保证公平性及降低功耗&#xff0c;当虚拟机vCPU空闲时&#xff0c;虚拟机将执行WFx/HLT指令退出到宿主机中&#xff0c;并触发上…

计算机视觉 - 基于黄金模板比较技术的缺陷检测

一、黄金模板比较概述 基于黄金模板比对的检测是一种常见的视觉应用。当进行缺陷检查而其他缺陷检测方法是不可行的时候,使用金模板比较。另外当物体的表面或物体的形状非常复杂时,此技术特别有用。 虽然说黄金模板比较的技术的思路很简单,但是真正落地实施确不是一件十分容…

广告数仓:数仓搭建(二)

系列文章目录 广告数仓&#xff1a;采集通道创建 广告数仓&#xff1a;数仓搭建 广告数仓&#xff1a;数仓搭建(二) 文章目录 系列文章目录前言DWD层创建1.建表广告事件事实表 2.数据装载初步解析日志解析IP和UA标注无效流量编写脚本 总结 前言 这次我们完成数仓剩下的内容 D…

Web服务器群集:Web基础与HTTP协议

目录 一、理论 1.Web基础 2.HTTP协议 二、实验 1.浏览本地HTML页面 三、总结 一、理论 1.Web基础 &#xff08;1&#xff09;域名和DNS ① 域名 网络是基于TCP/IP 协议进行通信和连接的&#xff0c;每一台主机都有一个唯一的标识&#xff08;固定的IP地 址&#xff0…

【Java面试】什么是SpringMVC?它的工作流程是什么样子的?

文章目录 什么是MVC&#xff1f;MVC组件组件前端控制器DispatcherServlet处理器映射器HandlerMapping处理器适配器HandlAdapter视图解析器ViewResolver处理器Handler视图View 工作原理具体执行流程 什么是MVC&#xff1f; M&#xff1a;model&#xff0c;模型层&#xff0c;包…

搅拌机打蒜机不转维修

打蒜机不转维修&#xff1a;打蒜机用的18650电池&#xff0c;霍尔传感器&#xff0c;Dp0206场效应管。故障为按一下开关显示红灯&#xff1a;电池电压低&#xff01;按下启动按钮电机动一下就再不动了。如果给电池两边加一个5伏电源&#xff0c;打蒜机电机运行正常。那么我把充…

【028】C++ 类和对象的 构造函数、析构函数、拷贝构造、初始化列表 详解(最全讲解)

C类和对象的构造函数、析构函数、拷贝构造、初始化列表详解 引言一、构造函数1.1、数据初始化和清理1.2、构造函数概述1.3、构造函数的定义1.4、提供构造函数的影响 二、析构函数三、拷贝构造函数3.1、拷贝构造的定义3.2、拷贝构造、无参构造、有参构造 三者的关系3.3、拷贝构造…

【群智能算法改进】一种改进的浣熊优化算法 改进长鼻浣熊优化算法 改进后的ICOA[1]算法【Matlab代码#41】

文章目录 【获取资源请见文章第5节&#xff1a;资源获取】1. 原始COA算法1.1 开发阶段1.2 探索阶段 2. 改进后的ICOA算法2.1 Circle映射种群初始化2.2 Levy飞行策略2.3 透镜成像折射反向学习策略 3. 部分代码展示4. 仿真结果展示5. 资源获取 【获取资源请见文章第5节&#xff1…

05-DataFrame的数据清洗

数据清洗 import pandas as pd df pd.read_excel("学生成绩.xlsx") df删除重复列 df.drop_duplicates(inplaceTrue) df删除数学成绩 df.drop([数学成绩],axis1, inplaceTrue) df重命名列名字 df.rename(columns{"生活":"自然"},inplaceTrue…

什么是Redis的BigKey,如何处理BigKey?

一、什么是BigKey BigKey通常以Key的大小和Key中成员的数量来综合判定&#xff0c;例如&#xff1a; Key本身的数据量过大&#xff1a;一个String类型的Key&#xff0c;它的值为5 MB。Key中的成员数过多&#xff1a;一个ZSET类型的Key&#xff0c;它的成员数量为10,000个。Ke…

Linux之多线程(下)——线程控制

文章目录 前言一、POSIX线程库1.概念2.pthread线程库是应用层的原生线程库3.错误的检查 二、线程控制1.创建线程——pthread_createpthread_create函数例子创建一个新线程主线程创建一批新线程 2.获取线程ID——pthread_self3.线程等待——pthread_join4.线程终止——return、p…

SSH服务器详解

文章目录 文字接口连接服务器&#xff1a;SSH服务器连接加密技术简介启动SSH服务SSH客户端连接程序SSH&#xff1a;直接登录远程主机的指令使用案例 服务器公钥记录文件&#xff1a;~/.ssh/known_hosts报错解决 模拟FTP的文件传输方式&#xff1a;SFTP使用案例 文件异地直接复制…

Python主要应用的10大领域你是否感兴趣

原文&#xff1a; Python主要应用的10大领域你是否感兴趣 Python 是一门快速发展的编程语言&#xff0c;其在各个领域的应用也在不断增加。根据 TIOBE 编程语言排行榜&#xff0c;Python 在 2021 年排名第 3&#xff0c;仅次于 Java 和 C。根据 Stack Overflow 的开发者调查报…