Conditional rendering and list rendering
Conditional Rendering
Conditional rendering in uni-app is primarily achieved through the v-if
, v-else-if
, v-else
, and v-show
directives. These directives control the display and hiding of elements based on the truthiness of expressions.
v-if
is true conditional rendering—it destroys or recreates DOM elements based on conditions. When the condition is false, the corresponding element and its child elements are not rendered into the DOM.
<view v-if="isShow">This element will be displayed or hidden based on the value of isShow</view>
v-else-if
and v-else
must immediately follow an element with v-if
or v-else-if
:
<view v-if="score >= 90">Excellent</view>
<view v-else-if="score >= 80">Good</view>
<view v-else-if="score >= 60">Pass</view>
<view v-else">Fail</view>
v-show
differs from v-if
in that it simply toggles the CSS display
property. Regardless of the condition, the element is always rendered and remains in the DOM:
<view v-show="isVisible">This element will always be rendered, only its display state will vary</view>
In terms of performance, v-show
is better for frequent toggling of display states, while v-if
is more suitable when the runtime condition is unlikely to change.
List Rendering
List rendering is primarily achieved through the v-for
directive, which can render an element or template block multiple times based on source data. In uni-app, the usage of v-for
is identical to Vue.js.
The basic syntax format is item in items
, where items
is the source data array and item
is an alias for the iterated array element:
<view v-for="item in items" :key="item.id">
{{ item.text }}
</view>
You can also use of
instead of in
as the separator:
<view v-for="item of items" :key="item.id">
{{ item.text }}
</view>
v-for
also supports a second parameter for the current item's index:
<view v-for="(item, index) in items" :key="index">
{{ index }} - {{ item.text }}
</view>
For objects, v-for
can iterate over the object's properties, providing three parameters: value, key, and index:
<view v-for="(value, key, index) in object" :key="key">
{{ index }}. {{ key }}: {{ value }}
</view>
The Importance of key
When using v-for
, providing a unique key
attribute for each node is crucial. The primary purpose of key
is to help Vue identify nodes, enabling the reuse and reordering of existing elements:
<view v-for="user in users" :key="user.id">
{{ user.name }}
</view>
If no suitable key
is available, you can use the index as a fallback:
<view v-for="(item, index) in items" :key="index">
{{ item }}
</view>
However, note that when the order of the list may change, using the index as key
can lead to performance issues and state errors.
Array Change Detection
Vue wraps array mutation methods, so these methods trigger view updates:
// These methods will trigger view updates
this.items.push(newItem)
this.items.pop()
this.items.shift()
this.items.unshift()
this.items.splice()
this.items.sort()
this.items.reverse()
However, directly setting an array item by index or modifying the array length will not trigger updates:
// These will not trigger updates
this.items[index] = newValue
this.items.length = newLength
To solve this, you can use Vue.set
or splice
:
// Correct approach
Vue.set(this.items, index, newValue)
// or
this.items.splice(index, 1, newValue)
Using v-for
on Components
When using v-for
on custom components, key
is required, and data must be passed via props
:
<my-component
v-for="(item, index) in items"
:key="item.id"
:item="item"
:index="index">
</my-component>
Combining Conditional and List Rendering
Conditional and list rendering are often combined, such as rendering only list items that meet specific conditions:
<template v-for="item in items">
<view v-if="item.isActive" :key="item.id">
{{ item.name }}
</view>
</template>
Alternatively, you can filter the array before rendering:
<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>
Performance Optimization Tips
For large lists, consider the following optimizations:
- Avoid using complex expressions in
v-for
. - Use
Object.freeze()
to freeze large lists that don't require reactive changes. - For very long lists, consider virtual scrolling techniques.
- Avoid using
v-if
andv-for
on the same element.
// Freeze large lists
this.items = Object.freeze(largeArray)
Common Issues and Solutions
- Priority of
v-if
andv-for
: When usingv-if
andv-for
on the same element,v-for
has higher priority. It's recommended to separate them:
<!-- Not recommended -->
<view v-for="item in items" v-if="item.isActive" :key="item.id">
{{ item.name }}
</view>
<!-- Recommended -->
<template v-for="item in items">
<view v-if="item.isActive" :key="item.id">
{{ item.name }}
</view>
</template>
- Dynamic filtering/sorting of lists: Use computed properties instead of filtering directly in the template:
computed: {
filteredItems() {
return this.items.filter(item => {
return item.name.match(this.searchQuery)
})
}
}
- Cross-platform differences: In uni-app, some platforms have special restrictions on list rendering. For example, in mini-programs, the
key
inv-for
must be a string or number.
本站部分内容来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn
上一篇:模板语法与数据绑定