14-Vue核心-列表渲染

使用 v-for 做列表渲染

我们可以用 v-for 指令基于一个数组来渲染一个列表,用于展示列表数据。

语法:

v-for = "(item, index) in items"  :key="xxx" 或者 v-for = "(item, index) of items"  :key="xxx" 

这里可以使用 of 替代 in 作为分隔符,因为它更接近 JavaScript 迭代器的语法。
:key 动态绑定key,可以理解为index,是遍历对象的唯一标识。
 
v-for 可以遍历以下类型:
1)遍历数组
<!--  遍历数组  -->
<h2>人员列表(遍历数组,用的多)</h2>
<ul>
    <!--  v-for 用于展示列表数据  -->
    <!--  :key 动态绑定key,可以理解为index,是遍历对象的唯一标识  -->
    <li v-for="(p,index) in persons" :key="index">
        姓名:{{p.name}}  年龄:{{p.age}}
    </li>
</ul>
 new Vue({
                el:"#root",
                data(){
                    return{
                        persons:[
                            {id:"001",name:"马铃薯1",age:20},
                            {id:"002",name:"马铃薯2",age:21},
                            {id:"003",name:"马铃薯3",age:22}
                        ]
                    }
                }
            })

2)遍历对象

<!--  遍历对象  -->
<h2>汽车信息(遍历对象)</h2>
<ul>
    <li v-for="(value,k) in car" :key="k">
        {{k}} : {{value}}
    </li>
</ul>
new Vue({
                el:"#root",
                data(){
                    return{
                        car:{
                            name:"奥迪A4L",
                            price:"27万",
                            color:"白色"
                        }
                    }
                }
            })

3)遍历字符串(用的少)

<!--  遍历字符串  -->
<h2>测试遍历字符串(用的少)</h2>
<ul>
    <li v-for="(value,index) in str" :key="index">
        {{index}} : {{value}}
    </li>
</ul>
new Vue({
                el:"#root",
                data(){
                    return{
                        str:"马铃薯的测试"
                    }
                }
            })

4)遍历指定次数(用的少)

<!--  遍历指定次数  -->
<h2>测试遍历指定次数(用的少)</h2>
<ul>
    <li v-for="(number,index) in 5" :key="index">
        {{index}} : {{number}}
    </li>
</ul>

 

基本列表渲染案例

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>基本列表</title>
        <!--  引入Vue  -->
        <script type="text/javascript" src="../js/vue.js"></script>
    </head>
    <body>
        <!--  准备好一个容器  -->
        <div id="root">
            <!--  遍历数组  -->
            <h2>人员列表(遍历数组,用的多)</h2>
            <ul>
                <!--  v-for 用于展示列表数据  -->
                <!--  :key 动态绑定key,可以理解为index,是遍历对象的唯一标识  -->

                <!--<li v-for="p in persons" :key="p.id">-->
                <!--    姓名:{{p.name}}  年龄:{{p.age}}-->
                <!--</li>-->
                <li v-for="(p,index) in persons" :key="index">
                    姓名:{{p.name}}  年龄:{{p.age}}
                </li>
            </ul>
            <!--  遍历对象  -->
            <h2>汽车信息(遍历对象)</h2>
            <ul>
                <li v-for="(value,k) in car" :key="k">
                    {{k}} : {{value}}
                </li>
            </ul>
            <!--  遍历字符串  -->
            <h2>测试遍历字符串(用的少)</h2>
            <ul>
                <li v-for="(value,index) in str" :key="index">
                    {{index}} : {{value}}
                </li>
            </ul>
            <!--  遍历指定次数  -->
            <h2>测试遍历指定次数(用的少)</h2>
            <ul>
                <li v-for="(number,index) in 5" :key="index">
                    {{index}} : {{number}}
                </li>
            </ul>
        </div>

        <script type="text/javascript">
            // 阻止 vue 在启动时生成生产提示
            Vue.config.productionTip = false

            new Vue({
                el:"#root",
                data(){
                    return{
                        persons:[
                            {id:"001",name:"马铃薯1",age:20},
                            {id:"002",name:"马铃薯2",age:21},
                            {id:"003",name:"马铃薯3",age:22}
                        ],
                        car:{
                            name:"奥迪A4L",
                            price:"27万",
                            color:"白色"
                        },
                        str:"马铃薯的测试"
                    }
                }
            })
        </script>

    </body>
</html>

思考一个问题

前面只是讲到,":key 动态绑定key,可以理解为index,是遍历对象的唯一标识"。这里我们想弄懂key的作用和原理,可以假设一个例子,如果我们有以下人员列表,想要在列表头部再新加一个人员,会出现什么问题吗

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>key的原理</title>
        <!--  引入Vue  -->
        <script type="text/javascript" src="../js/vue.js"></script>
    </head>
    <body>
        <!--  准备好一个容器  -->
        <div id="root">
            <!--  遍历数组  -->
            <h2>人员列表(遍历数组,用的多)</h2>
            <ul>
                <!--  v-for 用于展示列表数据  -->
                <!--  :key 动态绑定key,可以理解为index,是遍历对象的唯一标识  -->

                <!--<li v-for="p in persons" :key="p.id">-->
                <!--    姓名:{{p.name}}  年龄:{{p.age}}-->
                <!--</li>-->
                <li v-for="(p,index) in persons" :key="index">
                    姓名:{{p.name}}  年龄:{{p.age}}
                    <input type="text" placeholder="请输入文本信息">
                </li>
            </ul>

            <button @click.once="add">增加一个人员属性</button>
        </div>

        <script type="text/javascript" >
            // 阻止 vue 在启动时生成生产提示
            Vue.config.productionTip = false

            new Vue({
                el:"#root",
                data(){
                    return{
                        persons:[
                            {id:"001",name:"马铃薯1",age:20},
                            {id:"002",name:"马铃薯2",age:21},
                            {id:"003",name:"马铃薯3",age:22}
                        ]
                    }
                },
                methods:{
                    add(){
                        const p = {id:"004",name:"任先生4",age:26}
                        // unshift()向数组的头部添加元素
                        this.persons.unshift(p)
                    }
                }
            })
        </script>
    </body>
</html>

可以看到,新增加的人员信息,无法与后面的<input>标签对应上,也就是说通过:key="index"的方式,虽然是遍历对象的唯一标识,但是无法与遍历对象一一对应上。

<li v-for="(p,index) in persons" :key="index">
    姓名:{{p.name}}  年龄:{{p.age}}
    <input type="text" placeholder="请输入文本信息">
</li>

当修改为:key="p.id"的方式,问题解决

<li v-for="(p,index) in persons" :key="p.id">
    姓名:{{p.name}}  年龄:{{p.age}}
    <input type="text" placeholder="请输入文本信息">
</li>

 

Vue中key的作用与原理

在Vue中,key是虚拟DOM对象的标识,当状态中的数据发生变化时,Vue会根据【新数据】生成【新的虚拟DOM】,随后Vue进行【新虚拟DOM】与【旧虚拟DOM】的差异比较。

比较规则如下:

1)旧虚拟DOM中找到了与新虚拟DOM相同的key:

  • 若虚拟DOM中内容没变,直接使用之前的真实DOM
  • 若虚拟DOM中内容发生变化,则生成新的真实DOM,随后替换掉页面中之前的真实DOM

2)旧虚拟DOM中未找到与新虚拟机相同的key

  • 创建新的真实DOM,随后渲染到页面

使用index作为key可能会引发的问题

1)若对数据进行:逆序添加、逆序删除等破坏顺序操作,会产生没有必要的真实DOM更新 ==> 界面效果没问题,但效率低

2)如果结构中还包括输入类的DOM,会产生错误DOM更新 ==> 界面出现问题

开发中如何选择key

1)最好使用每条数据的唯一标识符作为key,比如id、手机号、身份证、学号等唯一值

2)如果不存在对数据的逆序添加、逆序删除等破坏顺序操作,仅用于渲染列表用于展示,使用index作为key也是没有问题的

 

 

posted @ 2023-09-19 22:48  马铃薯1  阅读(7)  评论(0编辑  收藏  举报