For AI agents: the complete documentation index is available at https://nhanbe.id.vn/llms.txt, the full documentation bundle is available at https://nhanbe.id.vn/llms-full.txt, and this page is available as Markdown at https://nhanbe.id.vn/frontend/vue2.7/conditional-rendering.md.

Vue 2.7 v-if, v-else-if, v-else, and v-show conditional rendering directives.

Conditional Rendering

Hiển thị hoặc ẩn phần tử dựa trên điều kiện. Trong AEM, dữ liệu thường đến từ Sling Model qua data attribute, nên điều kiện hay dùng để hiện block khi field có giá trị, ẩn khi rỗng.

v-if / v-else-if / v-else

v-if render phần tử khi điều kiện đúng. Khi sai, phần tử không tồn tại trong DOM.

<div v-if="status === 'active'">Đang hoạt động</div>
<div v-else-if="status === 'pending'">Chờ duyệt</div>
<div v-else>Không xác định</div>

Quy tắc: v-else và v-else-if phải nằm ngay sau phần tử có v-if (hoặc v-else-if), không được chèn phần tử khác ở giữa.

v-show

v-show luôn render phần tử vào DOM, chỉ bật/tắt bằng CSS display.

<div v-show="isVisible">Nội dung</div>

Khi isVisible sai, DOM vẫn có phần tử nhưng style="display: none".

v-if vs v-show

Tiêu chív-ifv-show
Cách hoạt độngThêm/xóa phần tử khỏi DOMGiữ trong DOM, đổi CSS display
Chi phí khi toggleCao (mount/unmount lại)Thấp (chỉ đổi CSS)
Chi phí render lần đầuThấp nếu điều kiện saiLuôn render
Hỗ trợ v-elseCóKhông
Dùng với templateCóKhông

Quy tắc chọn:

  • Toggle thường xuyên (tab, dropdown, accordion): dùng v-show.
  • Điều kiện ít đổi hoặc block nặng có thể không bao giờ hiện: dùng v-if.

Điều kiện cho nhóm phần tử với template

v-if chỉ áp cho một phần tử. Cần điều kiện cho nhiều phần tử mà không thêm thẻ bọc thừa thì dùng <template> (không render ra DOM).

<template v-if="hasContent">
  <h2>{{ title }}</h2>
  <p>{{ description }}</p>
</template>

v-show không dùng được với <template>.

v-if với v-for

Không đặt v-if và v-for trên cùng một phần tử. Ở Vue 2, v-for ưu tiên cao hơn v-if, nên v-if chạy lại cho từng item, gây khó đọc và tốn hiệu năng.

<!-- SAI: v-if chạy trên từng user -->
<li v-for="user in users" v-if="user.active" :key="user.id">
  {{ user.name }}
</li>

Cách đúng: lọc bằng computed trước, hoặc bọc v-if ra ngoài.

<!-- ĐÚNG: lọc bằng computed -->
<li v-for="user in activeUsers" :key="user.id">
  {{ user.name }}
</li>
computed: {
  activeUsers() {
    return this.users.filter(u => u.active)
  }
}

Điều kiện áp cho cả danh sách thì bọc ngoài bằng <template v-if>:

<template v-if="users.length">
  <li v-for="user in users" :key="user.id">{{ user.name }}</li>
</template>

key để kiểm soát tái sử dụng phần tử

Khi toggle giữa hai nhánh cùng loại phần tử, Vue tái sử dụng DOM cũ để tối ưu, có thể giữ lại state không mong muốn (vd giá trị input). Thêm key khác nhau để ép Vue render lại phần tử mới.

<input v-if="mode === 'email'" placeholder="Email" key="email">
<input v-else placeholder="Số điện thoại" key="phone">

Tips cho AEM

HTL đã render fallback HTML server-side. Khi Vue mount lên, dùng điều kiện để hiện block tương ứng dữ liệu từ Sling Model.

<!-- HTL render mount point + data -->
<div id="promo" data-promo="${model.promoJson}"></div>
new Vue({
  el: '#promo',
  data() {
    return {
      promo: JSON.parse(this.$el.dataset.promo || '{}')
    }
  }
})
<!-- template Vue -->
<div>
  <span v-if="promo.label" class="badge">{{ promo.label }}</span>
  <p v-else>Chưa có khuyến mãi</p>
</div>

Ưu tiên v-if cho block phụ thuộc field tùy chọn (có thể rỗng) để DOM gọn. Dùng v-show cho phần đóng/mở liên tục theo tương tác người dùng.