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的讲解。

相关文章
|
7天前
|
JavaScript 前端开发 算法
vue渲染页面的原理
vue渲染页面的原理
|
1月前
|
移动开发 JavaScript API
Vue Router 核心原理
Vue Router 是 Vue.js 的官方路由管理器,用于实现单页面应用(SPA)的路由功能。其核心原理包括路由配置、监听浏览器事件和组件渲染等。通过定义路径与组件的映射关系,Vue Router 将用户访问的路径与对应的组件关联,支持哈希和历史模式监听 URL 变化,确保页面导航时正确渲染组件。
|
1月前
|
监控 JavaScript 前端开发
ry-vue-flowable-xg:震撼来袭!这款基于 Vue 和 Flowable 的企业级工程项目管理项目,你绝不能错过
基于 Vue 和 Flowable 的企业级工程项目管理平台,免费开源且高度定制化。它覆盖投标管理、进度控制、财务核算等全流程需求,提供流程设计、部署、监控和任务管理等功能,适用于企业办公、生产制造、金融服务等多个场景,助力企业提升效率与竞争力。
95 12
|
1月前
|
JavaScript 前端开发 开发者
Vue中的class和style绑定
在 Vue 中,class 和 style 绑定是基于数据驱动视图的强大功能。通过 class 绑定,可以动态更新元素的 class 属性,支持对象和数组语法,适用于普通元素和组件。style 绑定则允许以对象或数组形式动态设置内联样式,Vue 会根据数据变化自动更新 DOM。
|
1月前
|
JavaScript 前端开发 数据安全/隐私保护
Vue Router 简介
Vue Router 是 Vue.js 官方的路由管理库,用于构建单页面应用(SPA)。它将不同页面映射到对应组件,支持嵌套路由、路由参数和导航守卫等功能,简化复杂前端应用的开发。主要特性包括路由映射、嵌套路由、路由参数、导航守卫和路由懒加载,提升性能和开发效率。安装命令:`npm install vue-router`。
|
JSON JavaScript 数据格式
【Vue 开发实战】基础篇 # 7:理解虚拟DOM及key属性的作用
【Vue 开发实战】基础篇 # 7:理解虚拟DOM及key属性的作用
136 0
【Vue 开发实战】基础篇 # 7:理解虚拟DOM及key属性的作用
|
3月前
|
JavaScript
vue使用iconfont图标
vue使用iconfont图标
168 1
|
2月前
|
JavaScript 安全 API
iframe嵌入页面实现免登录思路(以vue为例)
通过上述步骤,可以在Vue.js项目中通过 `iframe`实现不同应用间的免登录功能。利用Token传递和消息传递机制,可以确保安全、高效地在主应用和子应用间共享登录状态。这种方法在实际项目中具有广泛的应用前景,能够显著提升用户体验。
196 8
|
2月前
|
存储 设计模式 JavaScript
Vue 组件化开发:构建高质量应用的核心
本文深入探讨了 Vue.js 组件化开发的核心概念与最佳实践。
93 1
|
4月前
|
JavaScript 前端开发 开发者
vue 数据驱动视图
总之,Vue 数据驱动视图是一种先进的理念和技术,它为前端开发带来了巨大的便利和优势。通过理解和应用这一特性,开发者能够构建出更加动态、高效、用户体验良好的前端应用。在不断发展的前端领域中,数据驱动视图将继续发挥重要作用,推动着应用界面的不断创新和进化。
118 58