Vue Computed Properties
Mục lục
1. Diagram
- Computed Properties Flow
- Computed vs Methods
- Writable Computed
- Dependency Tracking
- Performance Comparison
2. Tổng quan
3. Basic Example
4. Computed Caching vs Methods
5. Writable Computed
6. Getting Previous Value (Vue 3.4+)
7. Best Practices
- Getters Should Be Side-Effect Free
- Avoid Mutating Computed Value
- Computed vs Watchers
- Keep Computed Simple
8. Common Use Cases
9. Kết luận
1. Diagram
Computed Properties Flow
Component Instance (Data / Methods / Computed)
|
v
Vue Template (HTML-based)
|
------------------------------------------------
| | |
{{ interpolation }} v-bind / :attr v-on / @event
| | |
Text Node Attribute Binding Event Listener
| | |
-------------------- Reactivity --------------------
|
v
Virtual DOM Diff
|
v
Real DOM Update
Computed vs Methods
+-------------------+ +-------------------+
| Computed Prop | | Method |
+-------------------+ +-------------------+
| - Định nghĩa trong | | - Định nghĩa trong |
| phần `computed` | | phần `methods` |
| - Tự động tính toán| | - Cần gọi thủ công|
| và cập nhật | | khi sử dụng |
| - Luôn luôn trả về | | - Có thể trả về |
| giá trị mới nhất | | giá trị tĩnh |
+-------------------+ +-------------------+
Writable Computed
+-------------------+ +-------------------+
| Read-only CP | | Writable CP |
+-------------------+ +-------------------+
| - Không thể gán giá| | - Có thể gán giá |
| trị mới | | trị mới |
| - Sử dụng khi chỉ | | - Sử dụng khi cần |
| cần đọc dữ liệu | | thay đổi dữ liệu |
+-------------------+ +-------------------+
Dependency Tracking
+-------------------+ +-------------------+
| Computed Prop | | Writable Prop |
+-------------------+ +-------------------+
| - Theo dõi sự thay| | - Theo dõi sự thay|
| đổi của phụ thuộc| | đổi của phụ thuộc|
| - Tự động cập nhật | | - Cần gọi hàm cập |
| khi phụ thuộc thay| | nhật thủ công |
+-------------------+ +-------------------+
Performance Comparison
+-------------------+ +-------------------+
| Computed Prop | | Method |
+-------------------+ +-------------------+
| - Được tối ưu hóa | | - Không được tối |
| cho hiệu suất cao| | ưu hóa tự động |
| - Thích hợp cho các | | - Thích hợp cho các|
| phép tính nặng | | tác vụ nhẹ |
+-------------------+ +-------------------+
2. Tổng quan
- Computed properties là gì?
- Là các thuộc tính được tính toán tự động dựa trên dữ liệu phản ứng (reactive data).
- Giúp tối ưu hiệu suất và tổ chức code tốt hơn.
- Khi nào nên dùng computed properties?
- Khi cần tính toán giá trị từ dữ liệu mà không muốn viết logic phức tạp trong template.
- Khi cần theo dõi và phản ứng với sự thay đổi của dữ liệu.
3. Basic Example
Vấn đề với Template Expression
- Giả sử có một bài toán đơn giản: hiển thị tên đầy đủ dựa trên tên và họ.
- Dùng template expression:
<span></span> - Vấn đề:
- Nếu tên hoặc họ thay đổi, Vue sẽ phải re-render toàn bộ phần tử.
- Không tối ưu cho hiệu suất.
Giải pháp: Computed Property
- Định nghĩa computed property trong component:
computed: { fullName() { return this.firstName + ' ' + this.lastName; } } - Sử dụng trong template:
<span></span> - Lợi ích:
- Tối ưu hiệu suất: chỉ re-render khi
firstNamehoặclastNamethay đổi. - Code rõ ràng, dễ bảo trì.
- Tối ưu hiệu suất: chỉ re-render khi
4. Computed Caching vs Methods
So sánh
| Tiêu chí | Computed Properties | Methods |
|---|---|---|
| Định nghĩa | Trong phần computed của component |
Trong phần methods của component |
| Gọi hàm | Tự động khi phụ thuộc thay đổi | Cần gọi thủ công trong template |
| Caching | Có, giá trị được lưu cache | Không, luôn luôn tính toán lại |
| Hiệu suất | Tối ưu hơn, nhất là với phép tính nặng | Thấp hơn, vì không có caching |
Ví dụ
- Ví dụ về computed properties:
computed: { // Giá trị đầy đủ của người dùng fullName() { return `${this.firstName} ${this.lastName}`; }, // Kiểm tra người dùng đã đăng nhập hay chưa isLoggedIn() { return !!this.userToken; } } - Ví dụ về methods:
methods: { // Đăng nhập người dùng login() { // Gọi API đăng nhập }, // Đăng xuất người dùng logout() { // Xóa token, thông tin người dùng } }
Khi nào computed KHÔNG update?
- Khi nào computed properties không tự động cập nhật giá trị?
- Khi không có sự thay đổi nào ở các thuộc tính phụ thuộc.
- Khi component không re-render do các lý do khác (ví dụ: không có sự kiện nào xảy ra).
5. Writable Computed
Mặc định: Read-only
- Computed properties trong Vue mặc định là read-only.
- Nghĩa là không thể gán giá trị mới cho computed property.
- Ví dụ:
computed: { // Computed property chỉ đọc readOnlyProp() { return this.someData; } } - Nếu cố gắng gán giá trị:
this.readOnlyProp = "new value"; // Không được phép
Tạo Writable Computed
- Để tạo writable computed, cần định nghĩa cả getter và setter.
- Ví dụ:
computed: { // Computed property có thể ghi writableProp: { // Getter get() { return this.someData; }, // Setter set(value) { this.someData = value; } } } - Sử dụng trong template:
<input v-model="writableProp" />
Use Case
- Khi nào nên sử dụng writable computed?
- Khi cần một thuộc tính vừa có thể đọc, vừa có thể ghi.
- Khi muốn kết hợp giữa computed properties và v-model.
6. Getting Previous Value (Vue 3.4+)
Read-only Computed
- Từ Vue 3.4, có thể dễ dàng lấy giá trị trước đó của một computed property.
- Ví dụ:
computed: { // Lấy giá trị trước đó của fullName previousFullName: { get() { return this.$options.computed.fullName.call(this, true); }, // Không định nghĩa setter, chỉ đọc } }
Writable Computed
- Với writable computed, cũng có thể lấy giá trị trước đó tương tự như read-only.
- Ví dụ:
computed: { // Lấy giá trị trước đó của writableProp previousWritableProp: { get() { return this.$options.computed.writableProp.get.call(this, true); }, set(value) { this.$options.computed.writableProp.set.call(this, value); } } }
7. Best Practices
1. Getters Should Be Side-Effect Free
- Các getter của computed properties không nên có side effects.
- Nghĩa là không nên thay đổi trạng thái của ứng dụng, gọi API, hay thực hiện các tác vụ không đồng bộ.
- Ví dụ sai:
computed: { // Sai, vì có side effect userData() { fetchUserData(); // Gọi API return this._userData; } } - Ví dụ đúng:
computed: { // Đúng, không có side effect userData() { return this._userData; } }
2. Avoid Mutating Computed Value
- Không nên thay đổi giá trị của computed property từ bên ngoài.
- Điều này có thể gây nhầm lẫn và khó debug.
- Thay vào đó, nên sử dụng các phương thức hoặc action để thay đổi trạng thái.
3. Computed vs Watchers
- Khi nào nên dùng computed properties, khi nào nên dùng watchers?
- Dùng computed properties khi cần tính toán và trả về giá trị.
- Dùng watchers khi cần thực hiện tác vụ không đồng bộ hoặc có side effect.
4. Keep Computed Simple
- Các computed properties nên được giữ đơn giản và dễ hiểu.
- Tránh viết quá nhiều logic phức tạp trong đó.
- Nếu một computed property quá phức tạp, hãy xem xét tách nó thành nhiều computed property nhỏ hơn.
8. Common Use Cases
- Một số trường hợp thường gặp khi sử dụng computed properties:
- Tính toán giá trị từ nhiều nguồn dữ liệu khác nhau.
- Định dạng dữ liệu trước khi hiển thị.
- Lọc hoặc sắp xếp danh sách dựa trên các tiêu chí nhất định.
9. Kết luận
- Computed properties là một phần quan trọng trong Vue.js, giúp tối ưu hiệu suất và tổ chức code tốt hơn.
- Hiểu và sử dụng đúng cách computed properties sẽ giúp bạn viết được những ứng dụng Vue.js mạnh mẽ và hiệu quả.