v-for
说明:v-for指令基于一个数组来为我们渲染一个列表,可以是为我们减少重复代码是编写,减少代码的重复,也可用于一些计算方面
语法:<组件 v-for="迭代别名 in 迭代数组(源数据数组[对象])">{{ 迭代别名[.属性] }}</组件>
<!-- 语法1 -->
<view v-for="item in items">{{ item.id }}--{{item.name}}</view>
<br />
<!-- 语法2 -->
<view v-for="(item,index) in items">{{index}}--{{ item.id }}--{{item.name}}</view>
<!-- 语法3 -->
<br />
<view v-for="(item,index) in items" :key="items.id">{{index}}--{{item.id}}--{{item.name}}</view>
其中:
item就是迭代别名;
items就是迭代数组;
index就是下标;
:key=v-bind:key绑定一个属性用于唯一标识这个列表(容器),可用于删除
v-for使用范围值渲染:
<template>
<!-- <view>111111</view>
<view>222222</view>
<view>333333</view>
<view>444444</view>
<view>555555</view>
<view>666666</view>
<view>777777</view>
<view>888888</view> -->
<view v-for="n in 9">渲染的第:{{n}}个列表</view>
</template>
从示例可以看出来,如果我们不用v-for来渲染容器的话,需要重复的编写同样的代码,造成了代码重复,用了v-for的组件,一行代码就生成了多个容器。
v-for使用数组渲染:
<template>
<view v-for="(item,index) in items"> 电脑品牌:{{ index+1 }}--{{ item }}</view>
</template>
<script setup>
import {ref} from "vue";
const items=ref(["联想","华硕","机械革命","火影","戴尔"])
</script>
<style lang="scss" scoped>
</style>
v-for使用对象渲染:
<template>
<view v-for="item in food">{{item}}</view>
</template>
<script setup>
import {ref} from "vue";
const food=ref({
id:"ts1",
name:"牛排",
price:"500"
})
</script>
<style lang="scss" scoped>
</style>
v-for使用有数组值中有对象的数组渲染:
<template>
<view v-for="(item,index) in items" :key="items.id">手机品牌:下标:{{index}} 编号:{{item.id}} 名称:{{ item.name }}</view>
</template>
<script setup>
import {ref} from "vue";
const items=ref([
{id:'TOP1',name:"华为"},
{id:'TOP2',name:"苹果"},
{id:'TOP3',name:"小米"},
{id:'TOP4',name:"荣耀"},
{id:'TOP5',name:"oppo"},
{id:'TOP6',name:"vivo"},
])
</script>
<style lang="scss" scoped>
</style>
注意点:
1.v-for和v-if不推荐一起使用,因为它们的优先级不明显,如果它们两个存在同一个组件上的话,v-if的优先级要高于v-for,并且因为级别v-if优先级高了之后就访问不到v-for作用域里面定义的变量了,所以使用的时候要根据实际情况使用;如果实在有这方便的需求的话可以在外层套一个template,如:官方文档的例子:
<template v-for="todo in todos">
<li v-if="!todo.isComplete">
{{ todo.name }}
</li>
</template>
2.key不要用下标(index)来做唯一标识这个元素,用一个小案例来解释为什么不要用index做唯一标识
key案例:
<template>
<view class="box">
<view class="item" v-for="(item,index) in items" :key="index">
<checkbox></checkbox>
<text class="title">{{ item.name }}</text>
<text class="del" @click="remove(index)">删除</text>
</view>
</view>
</template>
<script setup>
import {ref} from "vue";
const items=ref([
{id:'TOP1',name:"华为"},
{id:'TOP2',name:"苹果"},
{id:'TOP3',name:"小米"},
{id:'TOP4',name:"荣耀"},
{id:'TOP5',name:"oppo"},
{id:'TOP6',name:"vivo"},
])
function remove(index){
items.value.splice(index,1);
}
</script>
<style lang="scss" scoped>
.box{
padding: 10px;
.item{
padding: 8px 0;
.del{
color: red;
margin-left: 50px;
}
}
}
</style>
v-for中key用index的问题
可以从案例视频里面看出,当我们选中手机品牌为苹果的复选框时去删除华为的话复选框又变成了小米时选中的状态,这是因为index是实时更新的值,不会因为你删除了下标为0的元素后,下标为1的还是原来没有删除前的元素,它是会把剩下的元素重新从0开始分配下标,解决的办法就是key不用index作为值,用能够唯一标识这个元素的东西作为key,修改如下:
<template>
<view class="box">
<view class="item" v-for="(item,index) in items" :key="item.id">
<checkbox></checkbox>
<text class="title">{{ item.name }}</text>
<text class="del" @click="remove(index)">删除</text>
</view>
</view>
</template>
<script setup>
import {ref} from "vue";
const items=ref([
{id:'TOP1',name:"华为"},
{id:'TOP2',name:"苹果"},
{id:'TOP3',name:"小米"},
{id:'TOP4',name:"荣耀"},
{id:'TOP5',name:"oppo"},
{id:'TOP6',name:"vivo"},
])
function remove(index){
items.value.splice(index,1);
}
</script>
<style lang="scss" scoped>
.box{
padding: 10px;
.item{
padding: 8px 0;
.del{
color: red;
margin-left: 50px;
}
}
}
</style>
用id等能够唯一标识的来解决v-for删除问题