Tìm kiếm và lọc Todo nâng cao là bài học rất quan trọng để nâng tầm Todo App, giúp người dùng dễ dàng lọc và tìm công việc mình quan tâm.
Mục tiêu:
- Thêm bộ lọc theo trạng thái: Tất cả – Đã làm – Chưa làm
- Thêm thanh Tìm kiếm theo từ khóa
- Dùng computed property để xử lý danh sách lọc
Bước 1: Cập nhật TodoList.vue
<template>
<div>
<div class="filter">
<button :class="{active: filter === 'all'}" @click="filter = 'all'">Tất cả</button>
<button :class="{active: filter === 'done'}" @click="filter = 'done'">✅ Đã làm</button>
<button :class="{active: filter === 'undone'}" @click="filter = 'undone'">📋 Chưa làm</button>
<input v-model="keyword" placeholder="🔍 Tìm kiếm..." />
</div>
<p v-if="store.loading">⏳ Đang tải...</p>
<p v-if="store.error" class="error">❌ {{ store.error }}</p>
<TodoItem
v-for="todo in filteredTodos"
:key="todo.id"
:todo="todo"
@toggle="store.toggleTodo"
@delete="store.deleteTodo"
/>
</div>
</template>
<script setup>
import { ref, computed, onMounted } from 'vue'
import { useTodoStore } from '@/store/todoStore'
import TodoItem from './TodoItem.vue'
const store = useTodoStore()
onMounted(() => store.fetchTodos())
const filter = ref('all')
const keyword = ref('')
const filteredTodos = computed(() => {
return store.todos.filter(todo => {
const matchStatus =
filter.value === 'all' ||
(filter.value === 'done' && todo.completed) ||
(filter.value === 'undone' && !todo.completed)
const matchKeyword = todo.title.toLowerCase().includes(keyword.value.toLowerCase())
return matchStatus && matchKeyword
})
})
</script>
<style scoped>
.filter {
margin-bottom: 16px;
}
.filter button {
margin-right: 8px;
padding: 5px 10px;
}
.filter button.active {
background-color: #2b8a3e;
color: white;
}
.filter input {
margin-left: 10px;
padding: 6px;
width: 200px;
}
</style>
Giải thích:
Thành phần | Vai trò |
---|---|
filter | Biến trạng thái lọc: all , done , undone |
keyword | Chuỗi tìm kiếm nhập vào |
filteredTodos | Danh sách sau khi lọc theo cả 2 tiêu chí |
computed() | Theo dõi filter , keyword , store.todos và tự cập nhật danh sách |
Tổng kết:
Bạn đã làm được:
- Bộ lọc thông minh cho danh sách
- Tìm kiếm theo từ khóa
- Dùng
computed()
để tạo logic lọc dễ bảo trì và phản ứng tự động
Bài tập mở rộng:
- Hiển thị số lượng:
Tổng: 5 việc
Đã làm: 3 – Chưa làm: 2
- Thêm filter chọn nhiều tiêu chí nâng cao:
- Ví dụ: “Tìm việc chứa chữ ‘vue’ và chưa hoàn thành”
- Tích hợp bộ lọc nâng cao với localStorage để ghi nhớ lựa chọn
Thảo luận