Computed Property là gì? Khi nào nên dùng trong Vue.js?
Trong thế giới phát triển giao diện người dùng hiện đại, đặc biệt là với các framework như Vue.js, việc quản lý và hiển thị dữ liệu một cách hiệu quả là cực kỳ quan trọng. Một trong những tính năng mạnh mẽ nhất mà Vue.js cung cấp để giải quyết vấn đề này chính là computed property. Vậy computed property là gì, hoạt động như thế nào và khi nào chúng ta nên sử dụng nó? Bài viết này sẽ đi sâu vào khám phá khái niệm này.
Computed Property là gì?#
Trong Vue.js, computed property là một thuộc tính được tính toán dựa trên các thuộc tính reactive (dữ liệu) khác trong component. Nó không phải là một phương thức (method) thông thường mà là một thuộc tính có giá trị được tự động cập nhật khi bất kỳ dữ liệu phụ thuộc nào của nó thay đổi. Điều này có nghĩa là, khi bạn truy cập một computed property, Vue sẽ kiểm tra xem các dữ liệu mà nó phụ thuộc vào có thay đổi hay không. Nếu không, nó sẽ trả về giá trị đã được lưu trong bộ nhớ cache (cached value) từ lần tính toán trước đó. Nếu có, nó sẽ thực hiện lại việc tính toán và cập nhật giá trị mới.
Sự khác biệt cốt lõi giữa computed property và method nằm ở việc computed property có khả năng caching. Khi dữ liệu phụ thuộc không thay đổi, computed property sẽ không thực hiện lại quá trình tính toán, giúp tối ưu hóa hiệu suất ứng dụng, đặc biệt là với các phép tính phức tạp hoặc dữ liệu lớn. Ngược lại, một method sẽ luôn được gọi và thực thi mỗi khi nó được truy cập hoặc mỗi khi component re-render, ngay cả khi các dữ liệu liên quan không thay đổi.
Cú pháp cơ bản của Computed Property#
computed property được định nghĩa trong đối tượng computed của component Vue:
new Vue({ data: { firstName: 'John', lastName: 'Doe' }, computed: { fullName: function() { return this.firstName + ' ' + this.lastName; } } })
Trong ví dụ trên, fullName là một computed property. Nó phụ thuộc vào firstName và lastName. Bất cứ khi nào firstName hoặc lastName thay đổi, fullName sẽ tự động được cập nhật. Bạn có thể truy cập fullName trong template giống như một thuộc tính data thông thường:
`
Họ và tên: {{ fullName }}
`Computed Property với Setter (Getters và Setters)#
Mặc định, computed property chỉ có một getter function (hàm lấy giá trị). Tuy nhiên, bạn cũng có thể định nghĩa một setter function (hàm gán giá trị) nếu bạn muốn computed property có thể được gán giá trị ngược lại, và việc gán giá trị này sẽ ảnh hưởng đến các dữ liệu phụ thuộc của nó.
new Vue({ data: { firstName: 'John', lastName: 'Doe' }, computed: { fullName: { get: function() { return this.firstName + ' ' + this.lastName; }, set: function(newValue) { var names = newValue.split(' '); this.firstName = names[0]; this.lastName = names[names.length - 1]; } } } })
Trong ví dụ này, khi bạn gán giá trị cho fullName (ví dụ: this.fullName = 'Jane Smith'), hàm set sẽ được gọi, và nó sẽ cập nhật firstName và lastName tương ứng.
Khi nào nên dùng Computed Property?#
Việc lựa chọn sử dụng computed property hay method phụ thuộc vào tình huống cụ thể. Dưới đây là những trường hợp mà computed property là lựa chọn ưu việt:
1. Xử lý logic phức tạp để hiển thị dữ liệu#
Khi bạn cần thực hiện các phép biến đổi, tính toán, hoặc lọc dữ liệu trước khi hiển thị chúng trên giao diện. Thay vì đặt logic này trực tiếp vào template (điều này sẽ làm template trở nên khó đọc và khó bảo trì) hoặc trong một method (mà sẽ re-evaluate mỗi lần re-render), computed property cung cấp một cách sạch sẽ và hiệu quả để làm điều đó.
Ví dụ: Tính tổng giỏ hàng, lọc danh sách sản phẩm, định dạng ngày tháng, v.v.
new Vue({ data: { products: [ { id: 1, name: 'Laptop', price: 1200, quantity: 1 }, { id: 2, name: 'Mouse', price: 25, quantity: 2 }, { id: 3, name: 'Keyboard', price: 75, quantity: 1 } ] }, computed: { totalPrice: function() { return this.products.reduce((sum, product) => sum + (product.price * product.quantity), 0); }, affordableProducts: function() { return this.products.filter(product => product.price < 100); } } })
Trong ví dụ này, totalPrice và affordableProducts chỉ được tính toán lại khi mảng products thay đổi, giúp tiết kiệm tài nguyên.
2. Tối ưu hiệu suất với caching#
Đây là lợi ích lớn nhất của computed property. Nếu bạn có một phép tính tốn kém tài nguyên và kết quả của nó không thay đổi trừ khi dữ liệu đầu vào của nó thay đổi, thì computed property là lựa chọn hoàn hảo. Vue sẽ tự động lưu trữ kết quả và chỉ tính toán lại khi cần thiết.
Ví dụ: Một phép tính toán phức tạp dựa trên một mảng lớn.
new Vue({ data: { largeDataArray: [...Array(10000).keys()] // Mảng lớn }, computed: { processedData: function() { console.log('Calculating complex data...'); // Chỉ log khi thực sự tính toán return this.largeDataArray.map(item => item * 2).filter(item => item % 3 === 0); } } })
Nếu bạn sử dụng một method cho processedData, dòng console.log sẽ xuất hiện mỗi khi component re-render, ngay cả khi largeDataArray không đổi. Với computed property, nó chỉ chạy một lần và sử dụng kết quả đã cache cho các lần truy cập tiếp theo cho đến khi largeDataArray thay đổi.
3. Tạo thuộc tính dẫn xuất từ các thuộc tính khác#
Khi bạn muốn tạo một thuộc tính mới có giá trị được suy ra trực tiếp từ một hoặc nhiều thuộc tính data khác, computed property là lý tưởng. Điều này giúp giữ cho data của bạn gọn gàng và tập trung vào dữ liệu gốc, trong khi computed quản lý các giá trị dẫn xuất.
Ví dụ: Tạo một đường dẫn ảnh đầy đủ từ một tên file ảnh và base URL.
new Vue({ data: { imageName: 'profile.jpg', baseUrl: 'https://example.com/images/' }, computed: { fullImageUrl: function() { return this.baseUrl + this.imageName; } } })
4. Dễ đọc và dễ bảo trì mã nguồn#
Việc nhóm các logic tính toán dữ liệu vào computed property giúp mã nguồn của bạn trở nên gọn gàng, dễ đọc và dễ bảo trì hơn rất nhiều. Template chỉ tập trung vào việc hiển thị dữ liệu, trong khi các phép biến đổi được tách biệt rõ ràng.
So sánh Computed Property và Method#
Để củng cố sự hiểu biết, hãy cùng nhìn vào bảng so sánh giữa computed property và method:
| Tính năng | Computed Property | Method |
|---|---|---|
| Caching | Có (cache kết quả dựa trên các dependency) | Không (luôn thực thi mỗi lần gọi) |
| Khi nào thực thi | Khi các dependency thay đổi | Mỗi khi được gọi |
| Mục đích chính | Xử lý và hiển thị dữ liệu dẫn xuất | Thực hiện các hành động, logic nghiệp vụ |
| Đối số | Không thể truyền trực tiếp đối số | Có thể truyền đối số |
| Cú pháp gọi | Truy cập như một thuộc tính ({{ myComputed }}) |
Gọi như một hàm ({{ myMethod() }}) |
| Tối ưu hiệu suất | Tốt hơn cho các phép tính phức tạp và lặp lại | Kém hơn cho các phép tính phức tạp và lặp lại |
Khi nào nên dùng Method (thay vì Computed Property)?#
Mặc dù computed property rất mạnh mẽ, nhưng có những trường hợp mà method là lựa chọn phù hợp hơn:
Khi bạn cần truyền đối số:
computed propertykhông thể nhận đối số. Nếu bạn cần một hàm thực hiện một hành động dựa trên các đối số được truyền vào, hãy sử dụngmethod.methods: { getProductById: function(id) { return this.products.find(p => p.id === id); } }Khi bạn muốn thực hiện các tác vụ phụ (side effects):
computed propertychỉ nên được dùng để tính toán và trả về giá trị mà không gây ra bất kỳ tác dụng phụ nào (như thay đổi dữ liệu khác, gọi API, v.v.). Nếu bạn cần thực hiện các tác vụ này, hãy sử dụngmethod.Khi bạn không cần caching: Nếu phép tính của bạn rất đơn giản và không tốn kém tài nguyên, hoặc nếu bạn muốn nó luôn được thực thi mỗi khi được gọi (ví dụ: một hàm định dạng chuỗi đơn giản), thì
methodcó thể là đủ.
Kết luận#
Computed property là một tính năng không thể thiếu trong Vue.js, giúp các nhà phát triển xử lý và hiển thị dữ liệu một cách hiệu quả, rõ ràng và tối ưu về hiệu suất. Bằng cách hiểu rõ cách chúng hoạt động và khi nào nên sử dụng chúng, bạn có thể viết mã Vue.js sạch hơn, mạnh mẽ hơn và dễ bảo trì hơn. Hãy luôn ưu tiên computed property cho các logic tính toán dữ liệu dẫn xuất và chỉ sử dụng method khi bạn cần thực hiện các hành động hoặc truyền đối số.
Bài liên quan trong #VueJS
-
Vue.js Reactive System là gì? Khám phá cơ chế phản ứng của Vue
topdev -
Cách Disable Button Dựa Trên Điều Kiện: Hướng Dẫn Chi Tiết Chuẩn SEO
topdev -
Cách Render HTML Thô Trong Vue.js Với v-html: Hướng Dẫn Chi Tiết
topdev -
Làm Sao Để Bind Class Hoặc Style Động Trong Vue.js?
topdev -
This trong Vue trỏ tới đâu? Khám phá sức mạnh của Context trong Vue.js
topdev