Skip to content

Vue 列表渲染

Vue 列表渲染

简介

列表渲染主要指的是基于一组数据来渲染一个列表,通过指令 v-for 来实现,这个数据可以是数组或者一个对象。

比如在一个页面中,需要将请求的数据,展示到一个表格中,此时表格中的行就可以使用列表渲染实现。

通过列表渲染可以简化代码量。

格式:

<div v-for="item in items"> 
    {{ item }}
</div>
  • v-for 指令实现列表渲染。
  • item in items 是为 v-for 提供数据源
    • items 是被迭代的源数据数组
    • item 是被迭代的数组元素的别名

列表渲染简单数组

普通迭代渲染

在进行列表渲染时,直接使用数组中的元素值。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <!-- 引入 Vue -->
    <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
    <script>
        const {createApp, ref} = Vue

        window.onload = function(){
            createApp({
                setup() {
                    const data = ref(["Apple", "Orange", "Banana", "Pear"])
                    // 返回响应式变量或其他数据
                    return {
                        data
                    }
                }
            }).mount('#app');
        }
      </script>
</head>
<body>
    <div id="app">
        <ul>
            <li v-for="item in data"> {{ item }}</li>
        </ul>
    </div>
</body>
</html>

带索引迭代渲染

v-for 还支持一个可选的第二个参数为当前项的索引。

注意:如果使用索引,则该参数只能作为第二个参数。

<li v-for="(item, index) in data">
    {{index}} - {{item}}
</li>

列表渲染对象

渲染对象的值

v-for 指令也可以对 JS 对象进行列表渲染,在渲染时迭代的是 JS对象的值。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <!-- 引入 Vue -->
    <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
    <script>
        const {createApp, ref} = Vue

        window.onload = function(){
            createApp({
                setup() {
                    const data = ref({
                        name: "Tom",
                        age: 22,
                        gender: "male",
                        address: "BeiJing"
                    })
                    // 返回响应式变量或其他数据
                    return {
                        data
                    }
                }
            }).mount('#app');
        }
      </script>
</head>
<body>
    <div id="app">
        <ul>
            <li v-for="value in data"> {{ value }}</li>
        </ul>
    </div>
</body>
</html>

带属性名渲染对象

和对数组渲染相同,对 JS 对象进行渲染时,可以使用第二个参数接收 JS 对象的属性名。

也可以提供第二个的参数为键名:

<li v-for="(value, key) of data">
    {{key}} : {{value}}
</li>

带索引渲染对象

在渲染 JS 对象时,还可以接收第三个参数,用来获取索引。

注意:

  • 该索引只是 JS 对象中属性的一个编号
  • 不能在渲染 JS 对象时不使用属性参数而直接使用索引
<li v-for="(item, key, index) of items">
    {{index}} . {{key}} : {{item}}
</li>

多层数据列表渲染

在实际开发过程中,获取的数据大多是各种容器类型嵌套构成的,比如一个数组中包含了多个 JS 对象,而 JS 对象中的数据,才是真正要被渲染展示的数据。

此时,要根据实际数据的结构进行渲染。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <!-- 引入 Vue -->
    <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
    <script>
        const {createApp, ref} = Vue

        window.onload = function(){
            createApp({
                setup() {
                    // const data = ref(["Apple", "Orange", "Banana", "Pear"])
                    const data = ref([{
                        name: "Tom",
                        age: 22,
                        gender: "male",
                        address: "BeiJing"
                    },{
                        name: "Jack",
                        age: 23,
                        gender: "male",
                        address: "ShangHai"
                    },{
                        name: "Rose",
                        age: 52,
                        gender: "female",
                        address: "GuangZhou"
                    }])
                    // 返回响应式变量或其他数据
                    return {
                        data
                    }
                }
            }).mount('#app');
        }
      </script>
</head>
<body>
    <div id="app">
        <ul>
            <li v-for="(obj,index) in data"> 
              第{{index + 1}}个:{{obj.name}} -- {{obj.age}} -- {{obj.gender}} -- {{obj.address}}
            </li>
        </ul>
    </div>
</body>
</html>

通过 key 管理状态

Vue 默认按照就地更新的策略来更新通过 v-for 渲染的元素列表。

当数据项的顺序改变时,Vue 不会随之移动 DOM 元素的顺序,而是就地更新每个元素,确保它们在原本指定的索引位置上渲染。

默认模式是高效的,但只适用于列表渲染输出的结果数量和顺序不变的情况。

如果在对数据进行插入或乱序操作后,对数据会进行重新渲染时,可能会出现预料之外的效果。

这是因为 v-for 默认使用一个特殊属性 :key 来管理渲染元素的状态,Vue 默认使用 index 的值做为 key 的状态管理值,当重新渲染时,Vue 会对比相同 key 值中的内容,如果相同直接使用,如果不同则重新渲染。

为了避免渲染时出现问题,在使用 v-for 时,都绑定一个 :key 属性,一般情况下,做为 :key 值的数据推荐使用基础类型的值,并且具备唯一性。

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

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <!-- 引入 Vue -->
    <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
    <script>
        const {createApp, ref} = Vue

        window.onload = function(){
            createApp({
                setup() {
                    const data = ref([{
                        id:"s01",
                        name: "Tom",
                        age: 22,
                        gender: "male",
                        address: "BeiJing"
                    },{
                        id:"s02",
                        name: "Jack",
                        age: 23,
                        gender: "male",
                        address: "ShangHai"
                    },{
                        id:"s03",
                        name: "Rose",
                        age: 52,
                        gender: "female",
                        address: "GuangZhou"
                    }])

                    function addData(){
                        data.value.splice(0,0,{
                            id:"s04",
                            name: "Rony",
                            age: 26,
                            gender: "male",
                            address: "ShenZhen"
                        })
                    }
                    function changeData(){
                        data.value[0].name = "ROSE-A"
                        data.value[2].name = "TOM-A"
                    }
                    // 返回响应式变量或其他数据
                    return {
                        data,
                        addData,
                        changeData
                    }
                }
            }).mount('#app');
        }
      </script>
</head>
<body>
    <div id="app">
        <ul>
            <li v-for="(obj,index) in data" :key="index"> 
            <!-- <li v-for="(obj,index) in data" :key="obj.id">  -->
                <span>
                    第{{index + 1}}条数据:{{obj.id}} - {{obj.name}} - {{obj.age}} - {{obj.gender}} - {{obj.address}}
                </span>
                ---
                <span>
                    <input type="text">
                </span>

            </li>
        </ul>
        <div>
            <button @click="addData">添加数据</button> | <button @click="changeData">修改数据</button>
        </div>

</body>
</html>

总结

  • 列表渲染用来对重复结构的元素进行动态生成,提高代码开发效率,减少代码冗余。
  • 列表渲染时,推荐绑定一个唯一的值做为 :key 属性的值,避免出现渲染错误。