Vue之v-for(包含key内部原理讲解)

简介: Vue之v-for(包含key内部原理讲解)



前言

v-for:列表渲染


一、v-for

v-for将JSON数据中的数组或对象渲染出列表的样式呈现。

直接见代码实例,如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
    <div id="root">
        <h2>遍历数组</h2>
        <ul>
            <li v-for="(p,index) in person">
                {{p.id}}--{{p.name}}
            </li>
        </ul>
        <h2>遍历对象</h2>
        <ul>
            <li v-for="(value,key) in car">
                {{key}}--{{value}}
            </li>
        </ul>
        <h2>遍历字符串</h2>
        <ul>
            <li v-for="(char,index) in str">
                {{char}}--{{index}}
            </li>
        </ul>
        <h2>遍历次数</h2>
        <ul>
            <li v-for="(number,index) in 5">
                {{number}}--{{index}}
            </li>
        </ul>
    </div>
    <script>
        var vm = new Vue({
            el: "#root",
            data: {
                person: [{
                    id: "001",
                    name: "张三"
                }, {
                    id: "002",
                    name: "李四"
                }, {
                    id: "003",
                    name: "王五"
                }],
                car: {
                    name: "马自达",
                    price: "¥3000000"
                },
                str: "hello"
            }
        })
    </script>
</body>
</html>

二、key

1.介绍

  1. key的作用主要是为了高效的更新虛拟DOM,其原理是vue在patch(补丁)过程中通过key可以精准判断两个节点是否是同一个,从而避免频繁更新不同元素,使得整个patch过程更加高效,减少DOM操作量,提高性能。
  2. 另外,若不设置key还可能在列表更新时引发一些隐蔽的bug。如某行数据不该更新的却更新了。
  3. vue中在使用相同标签名元素的过渡切换时,也会使用到key属性,其目的也是为了让vue可以区分它们,否则vue只会替换其内部属性而不会触发过渡效果。

2.使用

格式:<标签 v-for="..." :key="唯一标识"></标签>

代码如下(示例):

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
    <div id="root">
        <button @click="add">点我添加老刘</button>
        <ul>
            <li v-for="(p,index) in person" :key="index">
                {{p.name}}--{{p.age}}
                <input type="text">
            </li>
        </ul>
    </div>
    <script>
        var vm = new Vue({
            el: "#root",
            data: {
                person: [{
                    id: "001",
                    name: "张三",
                    age: 18
                }, {
                    id: "002",
                    name: "李四",
                    age: 19
                }, {
                    id: "003",
                    name: "王五",
                    age: 20
                }]
            },
            methods: {
                add() {
                    const p = {
                        id: "004",
                        name: "老刘",
                        age: 40
                    }
                    this.person.unshift(p)
                }
            }
        })
    </script>
</body>
</html>

现在我们在页面上的文本框中添加对应信息,如下:

然后点击按钮,如下:

我们可以观察到老刘的文本框对应的是张三,张三对应的的文本框是李四,李四的文本框对应的是王五,王五空了,这是为什么吗呢,继续看下面!

3.原理

结合下面图片进行讲解:

上诉代码中key的值是与数组下标绑定的,添加老刘用的是unshift方法(将新的元素添加到数组最前面),所以老刘是第一个元素,key是0,其他依次。没有添加老刘前(图片左边),添加老刘后虚拟DOM改变(图片右边),在添加老刘后key发生变化,Vue内部的对比算法依据key值与原来的虚拟DOM比较(即key相同的进行比较),看下面图片,比较key=0的DOM对象,标签内文本不一样所以用更新后的,input,li标签一样继续沿用以前的,因此这就是上诉情况的原因:Vue的对比算法,对比的是虚拟DOM,而我们文本框填入对应信息是在真是DOM的操作,所以对比算法无法判断input内文本的改变,只知道input没改变,所以继续沿用的未添加前的key=0的li标签内的input。发生上述情况其实就是数组元素下标改变,key值对应发生变化,后面的都是这个原理。

当我们key与数组下标绑定时,要想不发生上诉情况,可以将老刘的添加用push方法(将元素添加到数组的最后),这样在添加后,原来的DOM对象key值没发生变化,按照数组下标。其实最好的方法是将key与上诉唯一标识id绑定,这样就可以忽略数组添加新元素的方法

4.总结

  1. 虚拟DOM中的key的作用:
    key是虚拟DOM对象的标识,当数据发生变化时,Vue会根据【新数据】生成【新的虚拟DOM】,随后Vue进行【新虚拟DOM】与【旧虚拟DOM】的差异比较。
  2. 对比规则:
    (1)旧虚拟DOM中找到了与新虚拟DOM相同的key:
    若虚拟DOM中内容没变,直接使用之前的真实DOM!
    若虚拟DOM中内容变了,则生成新的真实DOM,随后替换掉页面中之前的真实DOM
    (2)旧虚拟DOM中未找到与新虚拟DOM相同的key:
    创建新的真实DOM随后渲染到页面
  3. 用index作为key可能引发的问题:
    (1)若对数据进行:逆序添加、逆序删除等破坏顺序的操作:
    会产生没有必要的真实DOM更新==>界面效果没问题,但效率低
    (2)如果结构中还包含输入类的DOM:
    会产生错误DOM更新==>界面有问题
  4. 开发中如何选择key:
    (1)最好使用每条数据的唯一标识作为key,比如id、手机号、身份证号、学号等唯一值
    (2)如果不存在对数据的逆序添加、逆序删除等破坏顺序的操作,仅用于渲染列表用于展示,使用index作为key是没有问题的

总结

以上就是v-for和key的讲解。

相关文章
|
5天前
|
JavaScript
Vue基础知识总结 4:vue组件化开发
Vue基础知识总结 4:vue组件化开发
|
5天前
|
存储 JavaScript
Vue 状态管理工具vuex
Vue 状态管理工具vuex
|
10天前
|
JavaScript
如何在 Vue 中使用具名插槽
【10月更文挑战第25天】通过使用具名插槽,你可以更好地组织和定制组件的模板结构,使组件更具灵活性和可复用性。同时,具名插槽也有助于提高代码的可读性和可维护性。
15 2
|
10天前
|
JavaScript
Vue 中的插槽
【10月更文挑战第25天】插槽的使用可以大大提高组件的复用性和灵活性,使你能够根据具体需求在组件中插入不同的内容,同时保持组件的结构和样式的一致性。
13 2
|
10天前
|
前端开发 JavaScript 容器
在 vite+vue 中使用@originjs/vite-plugin-federation 模块联邦
【10月更文挑战第25天】模块联邦是一种强大的技术,它允许将不同的微前端模块组合在一起,形成一个统一的应用。在 vite+vue 项目中,使用@originjs/vite-plugin-federation 模块联邦可以实现高效的模块共享和组合。通过本文的介绍,相信你已经了解了如何在 vite+vue 项目中使用@originjs/vite-plugin-federation 模块联邦,包括安装、配置和使用等方面。在实际开发中,你可以根据自己的需求和项目的特点,灵活地使用模块联邦,提高项目的可维护性和扩展性。
|
JSON JavaScript 数据格式
【Vue 开发实战】基础篇 # 7:理解虚拟DOM及key属性的作用
【Vue 开发实战】基础篇 # 7:理解虚拟DOM及key属性的作用
115 0
【Vue 开发实战】基础篇 # 7:理解虚拟DOM及key属性的作用
|
12天前
|
数据采集 监控 JavaScript
在 Vue 项目中使用预渲染技术
【10月更文挑战第23天】在 Vue 项目中使用预渲染技术是提升 SEO 效果的有效途径之一。通过选择合适的预渲染工具,正确配置和运行预渲染操作,结合其他 SEO 策略,可以实现更好的搜索引擎优化效果。同时,需要不断地监控和优化预渲染效果,以适应不断变化的搜索引擎环境和用户需求。
|
12天前
|
缓存 JavaScript 搜索推荐
Vue SSR(服务端渲染)预渲染的工作原理
【10月更文挑战第23天】Vue SSR 预渲染通过一系列复杂的步骤和机制,实现了在服务器端生成静态 HTML 页面的目标。它为提升 Vue 应用的性能、SEO 效果以及用户体验提供了有力的支持。随着技术的不断发展,Vue SSR 预渲染技术也将不断完善和创新,以适应不断变化的互联网环境和用户需求。
30 9
|
11天前
|
缓存 JavaScript UED
Vue 中实现组件的懒加载
【10月更文挑战第23天】组件的懒加载是 Vue 应用中提高性能的重要手段之一。通过合理运用动态导入、路由配置等方式,可以实现组件的按需加载,减少资源浪费,提高应用的响应速度和用户体验。在实际应用中,需要根据具体情况选择合适的懒加载方式,并结合性能优化的其他措施,以打造更高效、更优质的 Vue 应用。
|
11天前
|
JavaScript 前端开发 UED
vue 提高 tree shaking 的效果
【10月更文挑战第23天】提高 Vue 中 Tree shaking 的效果需要综合考虑多个因素,包括模块的导出和引用方式、打包工具配置、代码结构等。通过不断地优化和调整,可以最大限度地发挥 Tree shaking 的优势,为 Vue 项目带来更好的性能和用户体验。
下一篇
无影云桌面