Vue3——v-for指令

v-for指令

1、遍历数组

v-for指令将根据接收到的数组中的数据重复渲染DOM元素。该指令需要使用item in items形式的语法,其中,items为数据对象中的数组名称,item为数组元素的别名,通过别名可以获取当前数组遍历的每个元素。

例如,应用v-for指令将

  • 标签循环渲染,输出数组中存储的职位名称。代码如下:
html 复制代码
<div id="app">
    <ul>
        <li v-for="item in items">{{item.position}}</li>
    </ul>
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script type="text/javascript">
    const vm = Vue.createApp({
        data() {
            return {
                items: [
                    {position: '前端工程师'},
                    {position: '一二线运维'},
                    {position: '项目经理'}
                ]
            }
        },
    }).mount('#app');//装载应用实例的根组件
</script>

在应用v-for指令遍历数组时,还可以指定一个参数作为当前数组元素的索引,语法格式为(item,index) initems。其中,items为数组名称,item为数组元素的别名,index为数组元素的索引。

例如,应用v-for指令将<li>标签循环渲染,输出数组中存 储的职位名称和相应的索引。代码如下:

html 复制代码
<div id="app">
    <ul>
        <li v-for="(item, index) in items">{{index}}-{{item.position}}</li>
    </ul>
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script type="text/javascript">
    const vm = Vue.createApp({
        data() {
            return {
                items: [
                    {position: '前端工程师'},
                    {position: '一二线运维'},
                    {position: '项目经理'}
                ]
            }
        },
    }).mount('#app');//装载应用实例的根组件
</script>

示例:输出商品信息。

应用v-for指令输出商品列表中的商品名称、商品类型以及商品价格,代码如下:

html 复制代码
<div id="app">
    <div class="title">
        <div class="col-1">序号</div>
        <div class="col-1">商品名称</div>
        <div class="col-1">商品类型</div>
        <div class="col-2">商品价格</div>
    </div>
    <div class="content" v-for="(goods, index) in goodslist">
        <div class="col-1">{{index + 1}}</div>
        <div class="col-1">{{goods.name}}</div>
        <div class="col-1">{{goods.type}}</div>
        <div class="col-2">{{goods.price}}</div>
    </div>
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script type="text/javascript">
    const vm = Vue.createApp({
        data() {
            return {
                goodslist: [
                    {name: '64GU盘', type: '外部设备', price: 39.9},
                    {name: '榨汁机', type: '家用电器', price: 169},
                    {name: '数码相机', type: '摄影摄像', price: 369},
                ]
            }
        },
    }).mount('#app');//装载应用实例的根组件
</script>

1.2、循环一组元素

与v-if指令类似,如果需要对一组元素进行循环,可以使用<template>元素作为包装元素,并在该元素上使用v-for。

html 复制代码
<div id="app">
    <ul>
        <template v-for="menu in munulist">
            <li class="item">{{menu}}</li>
        </template>
    </ul>
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script type="text/javascript">
    const vm = Vue.createApp({
        data() {
            return {
                munulist: ['首页', '课程', '读书', '社区', '服务中心']
            }
        },
    }).mount('#app');//装载应用实例的根组件
</script>

1.3、更新数组

Vue.js中包含了一些检测数组变化的变异方法,调用这些方法可以改变原始数组,并触发视图更新。这些变异方法的说明如表所示。

方法 说明
push() 向数组的末尾添加一个或多个元素
pop() 将数组中的最后一个元素从数组中删除
shift() 将数组中的第一个元素从数组中删除
unshift() 向数组的开头添加一个或多个元素
splice() 添加或删除数组中的元素
sort() 对数组的元素进行排序
reverse() 颠倒数组中元素的顺序

例如,应用变异方法push()向数组中添加一个元素,并应用v-for指令将<li>标签循环渲染,输出数组中存储的职位名称。代码如下:

html 复制代码
<div id="app">
    <ul>
        <li v-for="item in items">{{item.position}}</li>
    </ul>
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script type="text/javascript">
    const vm = Vue.createApp({
        data() {
            return {
                items: [
                    {position: '前端工程师'},
                    {position: '一二线运维'},
                    {position: '项目经理'},
                ]
            }
        },
    }).mount('#app');//装载应用实例的根组件
    vm.items.push({position: '系统管理员'});
</script>

示例:2022年手机销量排行榜。

将2022年手机销量排行榜前五名的手机品牌和销售市场份额定义在数组中,对数组按手机销售市场份额进行降序排序,将排序后的手机品牌排名、手机品牌和市场份额输出在页面中。代码如下:

html 复制代码
<div id="app">
    <div class="content" v-for="(phone, index) in phonelist">
        <div class="col-1">{{index + 1}}</div>
        <div class="col-2">{{phone.brand}}</div>
        <div class="col-1">{{phone.share}}</div>
    </div>
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script type="text/javascript">
    const vm = Vue.createApp({
        data() {
            return {
                phonelist: [
                    {brand: 'OPPP', share: 17.5},
                    {brand: '小米', share: 13.9},
                    {brand: '荣耀', share: 16.7},
                    {brand: 'iPhone', share: 18.0},
                ]
            }
        },
    }).mount('#app');//装载应用实例的根组件
    vm.phonelist.sort((a, b) => {
        return a.brand < b.brand ? 1 : -1;
    })
</script>

除了变异方法,Vue.js还包含了几个非变异方法,如filter()、concat()和slice()方法。调用这些方法不会改变原始数组,而是返回一个新的数组。当使用非变异方法时,可以用新的数组替换原来的数组。

例如,应用slice()方法获取数组中第一个元素后的所有元素,代码如下:

html 复制代码
<div id="app">
    <ul>
        <li v-for="item in items">{{item.position}}</li>
    </ul>
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script type="text/javascript">
    const vm = Vue.createApp({
        data() {
            return {
                items: [
                    {position: '前端工程师'},
                    {position: '一二线运维'},
                    {position: '项目经理'},
                ]
            }
        },
    }).mount('#app');//装载应用实例的根组件
    vm.items = vm.items.slice(1);
</script>

由于JavaScript的限制,Vue.js不能检测到通过修改数组长度引起的变化,如vm.items.length=2。为了解决这个问题,可以使用splice()方法修改数组的长度。例如,将数组的长度修改为2,代码如下:

html 复制代码
<div id="app">
    <ul>
        <li v-for="item in items">{{item.position}}</li>
    </ul>
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script type="text/javascript">
    const vm = Vue.createApp({
        data() {
            return {
                items: [
                    {position: '前端工程师'},
                    {position: '一二线运维'},
                    {position: '项目经理'},
                ]
            }
        },
    }).mount('#app');//装载应用实例的根组件
    vm.items.splice(2);
</script>

2、遍历对象

2.1、基本用法

应用v-for指令除了可以遍历数组,还可以遍历对象。遍历对象使用value in object形式的语法,其中,object为对象名称,value为对象属性值的别名。

例如,应用v-for指令将<li>标签循环渲染,输出对象中存储的员工信息。代码如下:

html 复制代码
<div id="app">
    <ul>
        <li v-for="value in employee">{{value}}</li>
    </ul>
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script type="text/javascript">
    const vm = Vue.createApp({
        data() {
            return {
                employee: {
                    name: '张三',
                    position: '前端工程师',
                    year: 10
                }
            }
        },
    }).mount('#app');//装载应用实例的根组件
</script>

在应用v-for指令遍历对象时,还可以使用第二个参数为对象属性名(键名)提供一个别名,语法格式为(value,key) in object。其中,object为对象名称,value为对象属性值的别名,key为对象属性名的别名。

例如,应用v-for指令输出对象中的属性名和属性值。代码如下:

html 复制代码
<div id="app">
    <ul>
        <li v-for="(value, key) in employee">{{key}}:{{value}}</li>
    </ul>
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script type="text/javascript">
    const vm = Vue.createApp({
        data() {
            return {
                employee: {
                    name: '张三',
                    position: '前端工程师',
                    year: 10
                }
            }
        },
    }).mount('#app');//装载应用实例的根组件
</script>

在应用v-for指令遍历对象时,还可以使用第三个参数为对象提供索引,语法格式为(value,key,index)inobject。其中,object为对象名称,value为对象属性值的别名,key为对象属性名的别名,index为对象的索引。

例如,应用v-for指令输出对象中的属性和相应的索引。

html 复制代码
<div id="app">
    <ul>
        <li v-for="(value, key, index) in employee">{{index}}-{{key}}:{{value}}</li>
    </ul>
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script type="text/javascript">
    const vm = Vue.createApp({
        data() {
            return {
                employee: {
                    name: '张三',
                    position: '前端工程师',
                    year: 10
                }
            }
        },
    }).mount('#app');//装载应用实例的根组件
</script>

2.2、向对象中添加响应式属性

如果需要向对象中添加一个或多个响应式属性,可以使用Object.assign()方法。在使用该方法时,需要将源对象的属性和新添加的属性合并为一个新的对象。

例如,应用Object.assign()方法向对象中添加两个新的属性。代码如下:

html 复制代码
<div id="app">
    <ul>
        <li v-for="(value, key, index) in employee">{{index}}-{{key}}:{{value}}</li>
    </ul>
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script type="text/javascript">
    const vm = Vue.createApp({
        data() {
            return {
                employee: {
                    name: '张三',
                    position: '前端工程师',
                    year: 10
                }
            }
        },
    }).mount('#app');
    vm.employee = Object.assign({}, vm.employee, {
        department: '开发部',
        entrytime: '2023年3月30日'
    });
</script>

3、遍历整数

v-for指令也可以遍历整数,接收的整数即为循环次数,根据循环次数将模板重复整数次。

例如,某单位正式员工的工作年限每增加一年,工龄工资就增长500元,输出一个工作5年的员工每一年的工龄工资增加情况,代码如下:

html 复制代码
<div id="app">
    <div v-for="n in 5">员工第{{n}}年工龄工资为{{n *salary}}元</div>
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script type="text/javascript">
    const vm = Vue.createApp({
        data() {
            return {
                salary: 500,
            }
        },
    }).mount('#app');
</script>


示例:输出九九乘法表。

html 复制代码
<div id="app">
    <div v-for="n in 9">
        <span v-for="m in n">
            {{m}} * {{n}}={{m*n}}
        </span>
    </div>
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script type="text/javascript">
    const vm = Vue.createApp({
        data() {
            return {
            }
        },
    }).mount('#app');
</script>

4、key属性

使用v-for指令渲染的元素列表在更新时,如果数据项的顺序被改变,Vue不会移动DOM元素来匹配数据项的顺序,而是就地更新每个元素。为了使Vue能跟踪每个DOM元素,需要为每一个数据项提供一个唯一的key属性。

下面是一个不使用key属性的示例,代码如下:

html 复制代码
<div id="app">
    <div>请输入职位:<input type="text" size="15" v-model="pos">
        <button v-on:click="add()">添加职位</button>
    </div>
    <p v-for="item in items">
        <input type="checkbox">
        <span>{{item.position}}</span>
    </p>
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script type="text/javascript">
    const vm = Vue.createApp({
        data() {
            return {
                pos: '',
                items: [
                    {position: '前端工程师'},
                    {position: '一二线工程师'},
                    {position: '项目经理'},
                ]
            }
        },
        methods: {
            add: function() {
                this.items.unshift({
                    position:this.pos
                })
            }
        }
    }).mount('#app');
</script>

在输入框中输入新的职位,单击"添加职位"按钮后,向职位数组开头添加了一个新职位,结果如图所示。

由结果可以看出,选择的选项变成了新添加的职位,产生问题的原因是v-for指令的"就地更新"策略。当向数组中添加内容时,指令只记住了刚开始选择的数组下标0,于是就选择了新数组中下标为0的选项。为了解决这个问题,需要在v-for指令的后面添加key属性。代码如下:

html 复制代码
<div id="app">
    <div>请输入职位:<input type="text" size="15" v-model="pos">
        <button v-on:click="add()">添加职位</button>
    </div>
    <p v-for="item in items" v-bind:key="item.position">
        <input type="checkbox">
        <span>{{item.position}}</span>
    </p>
</div>
相关推荐
橙子家28 分钟前
浏览器缓存之【结构化数据库与缓存】: IndexedDB、Cache storage 和 Storage buckets
前端
user205855615181334 分钟前
X6 中边悬浮置顶,规避 `mouseleave` 事件丢失问题
前端
李明卫杭州35 分钟前
CSS aspect-ratio 属性完全指南
前端
Pedantic3 小时前
SwiftUI 手势层级(Gesture Hierarchy)详解
前端
飘尘3 小时前
前端转型全栈(Java后端)的快速上手指引
前端·后端·全栈
一颗烂土豆3 小时前
Meshopt 压缩深度解析,为什么它比 Draco 更快
前端·javascript·webgl
浏览器工程师4 小时前
AI Agent 接浏览器任务,先别让它一路点到底
前端·后端
雨季mo浅忆4 小时前
VSCode自动格式化三要素
前端
爱勇宝5 小时前
深扒 Anthropic 1680 位工程师简历:应届生几乎没机会,AI 公司最缺的不是博士
前端·后端·程序员