条件渲染与列表渲染
条件渲染
条件渲染在uni-app中主要通过v-if
、v-else-if
、v-else
和v-show
指令实现。这些指令可以根据表达式的真假值来控制元素的显示与隐藏。
v-if
是真正的条件渲染,它会根据条件销毁或重建DOM元素。当条件为false时,对应的元素及其子元素不会被渲染到DOM中。
<view v-if="isShow">这个元素会根据isShow的值显示或隐藏</view>
v-else-if
和v-else
必须紧跟在v-if
或v-else-if
元素后面:
<view v-if="score >= 90">优秀</view>
<view v-else-if="score >= 80">良好</view>
<view v-else-if="score >= 60">及格</view>
<view v-else>不及格</view>
v-show
与v-if
不同,它只是简单地切换元素的CSS属性display
,无论条件真假,元素始终会被渲染并保留在DOM中:
<view v-show="isVisible">这个元素总是会被渲染,只是显示状态不同</view>
在性能方面,如果需要频繁切换显示状态,使用v-show
更好;如果运行时条件不太可能改变,则使用v-if
更合适。
列表渲染
列表渲染主要通过v-for
指令实现,它可以基于源数据多次渲染一个元素或模板块。在uni-app中,v-for
的用法与Vue.js完全一致。
基本语法格式为item in items
,其中items
是源数据数组,item
是被迭代的数组元素的别名:
<view v-for="item in items" :key="item.id">
{{ item.text }}
</view>
也可以使用of
替代in
作为分隔符:
<view v-for="item of items" :key="item.id">
{{ item.text }}
</view>
v-for
还支持第二个参数作为当前项的索引:
<view v-for="(item, index) in items" :key="index">
{{ index }} - {{ item.text }}
</view>
对于对象,v-for
可以遍历对象的属性,提供三个参数:值、键名和索引:
<view v-for="(value, key, index) in object" :key="key">
{{ index }}. {{ key }}: {{ value }}
</view>
key的重要性
在使用v-for
时,为每个节点提供唯一的key
属性非常重要。key
的主要作用是帮助Vue识别节点,从而重用和重新排序现有元素:
<view v-for="user in users" :key="user.id">
{{ user.name }}
</view>
如果没有合适的key
,可以使用索引作为备用方案:
<view v-for="(item, index) in items" :key="index">
{{ item }}
</view>
但要注意,当列表的顺序可能改变时,使用索引作为key
会导致性能问题和状态错误。
数组更新检测
Vue对数组的变异方法进行了包裹,所以这些方法触发视图更新:
// 这些方法会触发视图更新
this.items.push(newItem)
this.items.pop()
this.items.shift()
this.items.unshift()
this.items.splice()
this.items.sort()
this.items.reverse()
但是直接通过索引设置数组项或修改数组长度不会触发更新:
// 这些不会触发更新
this.items[index] = newValue
this.items.length = newLength
要解决这个问题,可以使用Vue.set
或splice
:
// 正确方式
Vue.set(this.items, index, newValue)
// 或
this.items.splice(index, 1, newValue)
在组件上使用v-for
在自定义组件上使用v-for
时,必须使用key
,并且数据需要通过props
传递:
<my-component
v-for="(item, index) in items"
:key="item.id"
:item="item"
:index="index">
</my-component>
条件渲染与列表渲染结合
条件渲染和列表渲染经常结合使用,例如只渲染满足特定条件的列表项:
<template v-for="item in items">
<view v-if="item.isActive" :key="item.id">
{{ item.name }}
</view>
</template>
或者先过滤数组再渲染:
<view v-for="item in activeItems" :key="item.id">
{{ item.name }}
</view>
<script>
export default {
computed: {
activeItems() {
return this.items.filter(item => item.isActive)
}
}
}
</script>
性能优化技巧
对于大型列表,可以考虑以下优化措施:
- 避免在
v-for
中使用复杂表达式 - 使用
Object.freeze()
冻结不需要响应式变化的大型列表 - 对于非常长的列表,考虑虚拟滚动技术
- 避免同时使用
v-if
和v-for
在同一个元素上
// 冻结大型列表
this.items = Object.freeze(largeArray)
常见问题与解决方案
v-if
和v-for
优先级问题:在同一个元素上使用v-if
和v-for
时,v-for
优先级更高。建议分开使用:
<!-- 不推荐 -->
<view v-for="item in items" v-if="item.isActive" :key="item.id">
{{ item.name }}
</view>
<!-- 推荐 -->
<template v-for="item in items">
<view v-if="item.isActive" :key="item.id">
{{ item.name }}
</view>
</template>
- 动态过滤/排序列表:使用计算属性而不是在模板中直接过滤:
computed: {
filteredItems() {
return this.items.filter(item => {
return item.name.match(this.searchQuery)
})
}
}
- 跨平台差异处理:在uni-app中,某些平台对列表渲染有特殊限制,例如小程序中
v-for
的key
必须是字符串或数字。
本站部分内容来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn
上一篇:模板语法与数据绑定