vue之列表循环

文档:https://cn.vuejs.org/v2/guide/list.html

当 Vue.js 用 v-for 正在更新已渲染过的元素列表时,它默认用“就地复用”策略。如果数据项的顺序被改变,Vue 将不会移动 DOM 元素来匹配数据项的顺序, 而是简单复用此处每个元素,并且确保它在特定索引下显示已被渲染过的每个元素。这个类似 Vue 1.x 的 track-by="$index"

意思就是,默认就是按照索引来“就地复用”html元素的,如以下代码

<div v-for="(item,index) in arr" :key="index">

等价于

<div v-for="(item,index) in arr">

对于“就地复用”这个现象,以下来重现一下:

测试代码

<template>
    <div>
        <div v-for="(item,index) in arr">
            <input type="text">
            <button @click="del(index)">删除</button>
        </div>
        <button @click="add">添加</button>
    </div>
</template>

<script>
    export default {
        name: "App",
        data() {
            return {
                arr: [
                    "1",
                    "2",
                    "3",
                ]
            }
        },
        methods: {
            del(index) {
                this.arr.splice(index, 1);
            },
            add() {
                this.arr.push("");
            }
        }
    }
</script>

往页面的输入框依次填入1~3:

然后点击第二个删除按钮,效果如下:

页面剩下1、2,这跟我们预期的剩下1、3不一样,原因就在于vue默认的“就地复用”原则。现象解释如下:

将以上三个输入框记为a,b,c。for循环默认的key为索引的话,则a对应0,b对应1,c对应2 。那当删了了第二个元素时,新数组的元素的索引分别为0和1,而重新渲染时,采用就地复用的话,复用到的dom元素就是a和b了,页面输入框就展示1和2了。这输入框中的1和2实际上就是代表了dom的状态,通过输入框的值,就能看出来,vue复用了哪个dom元素。这里说的,实际上就是对应了文档的第二段话:

这个默认的模式是高效的,但是只适用于不依赖子组件状态或临时 DOM 状态 (例如:表单输入值) 的列表渲染输出

也就是说,当dom有状态的时候,最好就不要采用这种默认模式(key为索引),否则会导致状态混乱(如上面我们明明点击了第二个删除,而页面展示的效果却像点击了第三个删除的按钮一样)。

对于循环渲染有状态的dom元素,应该让key与数组元素一一对应起来,这样数组元素的删除,就完全等同于对应dom元素的删除了(换个角度解释以上的问题就是:点击删除的前后,索引1对应着相同的dom元素,而对应的数组元素却不一致,导致页面展示的结果让人困惑),解决办法如下:

<div v-for="(item,index) in arr" :key="item">
    <input type="text">
    <button @click="del(index)">删除</button>
</div>

让key与数组元素唯一对应起来即可,运行效果:点击第二个删除,界面上剩余1,3,符合我们预期结果。但是这样一来,vue就不会就地复用,性能会相对低一点了。

原文地址:https://www.cnblogs.com/hellohello/p/10245505.html

时间: 2024-08-30 04:30:20

vue之列表循环的相关文章

Vue.js学习之条件v-if和列表循环v-for详解

本文将继续和大家分享Vue.js的基础知识,主要是介绍Vue.js的条件v-if和列表循环v-for的相关使用,一起来看看吧,希望可以帮助大家更好的学习Vue.js. v-if .v-else.v-show.还可以使用template <div v-if="ok">ok</div> <div v-else>No</div> <div v-show="ok">ok</div> <templa

Vue,品牌列表案例(仅添加,删除,搜索,全局过滤器,私有过滤器)

Vue,品牌列表案例(仅添加,删除,搜索,全局过滤器,私有过滤器) 添加了时间过滤器(私有的) 1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <title></title> 6 <script src="../../js/vue.js"></script> 7 <link rel=&qu

列表循环

列表循环(两种循环方式,非常重要): for item in a: print item 题目:列表a, 它的索引偶数项的值加1,输出新的列表 a = [2, 8, 1, 33, 43, 9, 3] for index, item in enumerate(a): print index, item

html+css+javascript实现列表循环滚动示例代码

使用html+css+javascript实现列表循环滚动,设置时间定时,在规定的时间内替换前一个节点的内容,具体示例如下,感兴趣的朋友可以参考下 说明:设置时间定时,在规定的时间内替换前一个节点的内容 1.关键代码:javascript: 代码如下: <script type="text/javascript"> var dome=document.getElementById("dome"); //获取节点 var dome1=document.ge

vue里面的v-for列表循环

列表渲染 v-for v-for可以把数据中的一个数组对应为一组元素v-for 指令需要以 item in items 形式的特殊语法, items 是源数据数组并且 item 是数组元素迭代的别名. <li v-for="item in items">{{item.text}}</li> data:{ items:[ {text:"第一组"}, {text:"第二组"}, {text:"第三组"},

vue animate.css训练动画案例 列表循环

制作目标动画:向上入场添加数据,点击数据右滑动离场 简单页面效果: 实现代码如下: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> <link rel="stylesheet" type="text/css" href="css/animate.css"/>

【03】Vue 之列表渲染及条件渲染

3.1. 条件渲染 有时候我们要根据数据的情况,决定标签是否进行显示或者有其他动作.最常见的就是,表格渲染的时候,如果表格没有数据,就显示无数据.如果有数据就显示表格数据. Vue帮我们提供了一个v-if的指令,帮助我们完成判断的模板处理. <div id="app"> <h1 v-if="ok">Yes</h1> <h1 v-else>No</h1> </div> <!-- 当ok为tr

vue中动态循环model

vue动态循环model与angular有所不同,angular直接定义一个数组,然后传入循环列表的index即可. 而vue不仅需要定义一个数组,还需要通过接口读出循环的数组长度,然后在create中先创建出来. <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> <script type="text/javas

Vue条件与循环

一.条件判断 1.v-if 条件判断使用 v-if 指令: 2.v-else 可以用 v-else 指令给 v-if 添加一个 "else" 块: //随机生成一个数字,判断是否大于0.5,然后输出对应信息: <div id="app"> <div v-if="Math.random() > 0.5"> Sorry </div> <div v-else> Not sorry </div&