Vue 3 là một framework hiện đại cho phần frontend, với những cải tiến đáng kể về hiệu suất, trải nghiệm phát triển và tính năng. Dưới đây sẽ là các đặc điểm cốt lõi của Vue 3 cùng với một ví dụ thực tế.
Đặc điểm chính của Vue 3
1. API Kết hợp (Composition API)
- Tổ chức và tái sử dụng logic linh hoạt hơn.
- Hỗ trợ tốt hơn cho TypeScript.
- Phân tách rõ ràng các mối quan tâm trong logic.
2. Nâng cao hiệu suất
- Kích thước gói nhỏ gọn hơn nhờ tối ưu hóa Tree-shaking.
- Tốc độ render nhanh hơn.
- Cơ chế re-render hiệu quả hơn.
3. Hỗ trợ TypeScript tốt hơn
- Định nghĩa đầy đủ kiểu dữ liệu TypeScript.
- Trải nghiệm phát triển mượt mà hơn.
Ví dụ thực tế: Quản lý công việc
Dưới đây là một ứng dụng quản lý công việc được xây dựng bằng Vue 3:
<html lang="vi-VN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Quản lý công việc với Vue 3</title>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: Arial, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
padding: 20px;
color: #333;
}
.container {
max-width: 800px;
margin: 0 auto;
}
.app-title {
text-align: center;
color: white;
margin-bottom: 30px;
font-size: 2.5rem;
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3);
}
.card {
background: white;
border-radius: 12px;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
padding: 25px;
margin-bottom: 20px;
}
.input-group {
display: flex;
margin-bottom: 20px;
}
.task-input {
flex: 1;
padding: 12px 15px;
border: 2px solid #e1e5e9;
border-radius: 8px 0 0 8px;
font-size: 16px;
transition: border-color 0.3s;
}
.add-btn {
background: #667eea;
color: white;
border: none;
padding: 12px 25px;
border-radius: 0 8px 8px 0;
cursor: pointer;
font-size: 16px;
transition: background 0.3s;
}
.filter-buttons {
display: flex;
gap: 10px;
margin-bottom: 20px;
}
.filter-btn.active {
background: #667eea;
color: white;
}
.task-list {
list-style: none;
}
.task-item:hover {
background: #f9f9f9;
}
.delete-btn {
background: #ff6b6b;
color: white;
border: none;
padding: 8px 12px;
border-radius: 6px;
cursor: pointer;
transition: background 0.3s;
}
</style>
</head>
<body>
<div id="app">
<div class="container">
<h1 class="app-title">Quản lý công việc</h1>
<div class="card">
<div class="input-group">
<input
v-model="newTask"
@keyup.enter="addTask"
class="task-input"
placeholder="Thêm công việc mới..."
type="text"
>
<button @click="addTask" class="add-btn">Thêm</button>
</div>
<div class="filter-buttons">
<button
@click="currentFilter = 'all'"
:class="['filter-btn', { active: currentFilter === 'all' }]"
>
Tất cả
</button>
<button
@click="currentFilter = 'active'"
:class="['filter-btn', { active: currentFilter === 'active' }]"
>
Đang làm
</button>
<button
@click="currentFilter = 'completed'"
:class="['filter-btn', { active: currentFilter === 'completed' }]"
>
Hoàn thành
</button>
</div>
<ul class="task-list">
<li v-for="job in filteredJobs" :key="job.id" class="task-item">
<input
type="checkbox"
v-model="job.isDone"
class="task-checkbox"
>
<span
:class="['task-text', { completed: job.isDone }]"
>
{{ job.name }}
</span>
<button @click="removeJob(job.id)" class="delete-btn">Xóa</button>
</li>
</ul>
<div v-if="jobs.length === 0" class="empty-state">
Chưa có công việc nào!
</div>
</div>
</div>
</div>
<script>
const { createApp, ref, computed } = Vue;
createApp({
setup() {
const newJob = ref('');
const jobs = ref([]);
const currentFilter = ref('all');
const filteredJobs = computed(() => {
if (currentFilter.value === 'active') {
return jobs.value.filter(job => !job.isDone);
} else if (currentFilter.value === 'completed') {
return jobs.value.filter(job => job.isDone);
}
return jobs.value;
});
const addJob = () => {
if (!newJob.value.trim()) return;
jobs.value.push({
id: Date.now(),
name: newJob.value.trim(),
isDone: false
});
newJob.value = '';
};
const removeJob = (id) => {
jobs.value = jobs.value.filter(job => job.id !== id);
};
return {
newJob,
jobs,
currentFilter,
filteredJobs,
addJob,
removeJob
};
}
}).mount('#app');
</script>
</body>
</html>
Phân tích khái niệm cốt lõi của Vue 3
1. API Kết hợp (Composition API)
Vue 3 giới thiệu Composition API để giải quyết vấn đề phân tách logic trong các thành phần phức tạp.
// Option API (Vue 2)
export default {
data() {
return {
value: 0
}
},
methods: {
increase() {
this.value++;
}
}
}
// Composition API (Vue 3)
import { ref } from 'vue'
export default {
setup() {
const value = ref(0);
function increase() {
value.value++;
}
return {
value,
increase
}
}
}
2. Hệ thống phản hồi
Vue 3 sử dụng Proxy để viết lại hệ thống phản hồi, mang lại hiệu suất tốt hơn và khả năng phản hồi hoàn chỉnh.
import { reactive, watch } from 'vue'
const state = reactive({
user: {
name: 'Người dùng',
age: 30
}
})
watch(() => state.user.age, (newValue, oldValue) => {
console.log(`Tuổi đã thay đổi từ ${oldValue} thành ${newValue}`);
});
3. Hook chu kỳ sống
Hook chu kỳ sống trong Composition API tương ứng với các hàm riêng biệt.
import { onMounted } from 'vue'
export default {
setup() {
onMounted(() => {
console.log('Thành phần đã được gắn');
})
}
}