Khi xây dựng giao diện với Vue.js, chắc hẳn bạn sẽ gặp phải tình huống: “Tôi chỉ muốn hiển thị phần này khi điều kiện này đúng, và ẩn nó khi điều kiện đó không thỏa.”
Vue có sẵn hai mệnh đề điều kiện rất phổ biến để xử lý trường hợp này: v-if và v-show. Trong bài viết này, chúng ta sẽ cùng tìm hiểu cách hoạt động, điểm khác biệt và trường hợp nào nên sử dụng cái nào.
1. v-if – DOM render “thực sự” theo điều kiện
Khi bạn dùng v-if, Vue sẽ thực sự thêm phần tử vào DOM khi điều kiện là true, và loại bỏ hoàn toàn phần tử đó (kèm event listeners, child components…) khi điều kiện trở thành false.
Ví dụ:
<h1 v-if="isLoggedIn">Chào mừng bạn!</h1>
Nếu isLoggedIn là false, <h1> sẽ không có trong DOM. Khi chuyển sang true, Vue sẽ tạo ra phần tử đó.
Bạn có thể dùng thêm v-else hoặc v-else-if để mở rộng logic điều kiện:
<div v-if="role === 'admin'">Dashboard Admin</div>
<div v-else-if="role === 'moderator'">Dashboard Moderator</div>
<div v-else>Dashboard User</div>
Một điểm lưu ý: nếu bạn muốn bật/tắt nhiều phần tử cùng lúc mà không muốn tạo wrapper thừa, bạn có thể quấn chúng trong <template v-if="…">…</template> — đó là cách Vue cho phép “nhóm” nhiều phần tử theo điều kiện.
Ưu & nhược
Ưu điểm:
- Khi điều kiện sai ngay từ đầu, Vue không render phần tử — tiết kiệm tài nguyên cho DOM.
- Hủy sạch event listener, child component khi ẩn → giúp tránh leak hoặc render không cần thiết.
Nhược điểm:
- Mỗi khi điều kiện chuyển đổi (false → true hoặc ngược lại), Vue phải tạo mới hoặc hủy phần tử → chi phí tốn hơn nếu toggle rất thường xuyên.
- Nếu bạn có phần tử lớn, phức tạp mà bật/tắt thường xuyên,
v-ifcó thể gây giật hoặc delay.
2. v-show – ẩn/hiện bằng CSS
Khác với v-if, khi bạn dùng v-show, Vue sẽ luôn render phần tử đó vào DOM ngay từ đầu, bất kể điều kiện là true hay false. Khi điều kiện là false, phần tử sẽ được ẩn đi bằng CSS (display: none); khi true thì trở lại hiển thị.
Ví dụ:
<h1 v-show="isVisible">Xin chào!</h1>
Dù isVisible là false, đoạn <h1> vẫn nằm trong DOM — chỉ là bị ẩn đi. Khi isVisible chuyển true, Vue chỉ cần thay đổi CSS để hiện lại, không cần tạo mới hoặc hủy.
Ưu & nhược
Ưu điểm:
- Toggle rất nhanh vì chỉ thao tác CSS — phù hợp khi bạn bật/tắt phần tử thường xuyên.
- Nếu phần tử tương đối nhẹ, đơn giản, việc render sẵn rồi show/hide có thể tối ưu hơn tạo/hủy liên tục.
Nhược điểm:
- Dù phần tử bị ẩn, nhưng vẫn nằm trong DOM — chiếm bộ nhớ, vẫn giữ event listener/child component (nếu có).
- Nếu phần tử rất phức tạp, và bạn hiếm khi show nó — render nó ngay từ đầu có thể là lãng phí.
3. Khi nào dùng cái nào?
Đây là kinh nghiệm thực tế để bạn chọn phù hợp:
- Nếu phần tử chỉ hiển thị rất ít lần, hoặc điều kiện hiển thị rất hiếm khi thay đổi → dùng
v-if. - Nếu phần tử bật/tắt thường xuyên, như tooltip, dropdown, modal, thông báo nhỏ → dùng
v-show. - Nếu phần tử lớn, phức tạp và chỉ dùng trong vài trường hợp đặc biệt → ưu tiên
v-if.
Một cách đơn giản:
- Toggle nhiều lần →
v-show. - Hiếm toggle →
v-if.
4. Một số lưu ý thêm
- Không khuyến khích dùng
v-ifvàv-fortrực tiếp trên cùng một phần tử vì ưu tiên thực thi có thể gây hiểu nhầm. v-showkhông hỗ trợ<template>nhưv-if(vì bản thân nó không “render” phần tử nếu điều kiện false).- Sử dụng computed properties hoặc methods để trả về điều kiện rõ ràng, tránh đưa logic phức tạp vào template — giúp code dễ hiểu và bảo trì.
- Nếu bạn mix cả animation/transition với việc toggle, thì tùy trường hợp: thường animation thích hợp hơn với
v-show(vì phần tử vẫn ở DOM), nhưng đôi khi bạn vẫn muốnv-ifnếu muốn unmount hoàn toàn khi ẩn.
Ví dụ minh họa DOM render
Giả sử bạn có một form đăng nhập và một thông báo lỗi nhỏ hiện rất thường — bạn có thể dùng v-show cho thông báo lỗi vì nó bật/tắt rất nhiều lần, và dùng v-if cho form đăng nhập nếu bạn chỉ hiển thị form sau khi tải dữ liệu hoặc khi user chưa đăng nhập.
<template>
<div>
<div v-if="!isLoggedIn">
<LoginForm @success="handleLogin"/>
</div>
<div v-show="isLoggingIn">
Đang đăng nhập… Vui lòng đợi.
</div>
<div v-show="loginError">
<span class="error">{{ loginErrorMessage }}</span>
</div>
</div>
</template>
Ở đây:
- Form chỉ hiện khi user chưa đăng nhập → dùng
v-if. - Thông báo đăng nhập và lỗi bật/tắt thường xuyên → dùng
v-show.
Kết lại
Việc hiểu rõ sự khác biệt giữa v-if và v-show giúp bạn tối ưu performance và trải nghiệm cho ứng dụng Vue của mình. Không có “một chỉ duy nhất đúng” — quan trọng là đánh giá phần tử đó sử dụng như thế nào, toggle bao nhiêu lần, và có tốn kém khi tạo/hủy hay không.
Hãy cân nhắc kỹ, và chọn đúng cho từng trường hợp cụ thể của bạn.
