Bài 5: Computed trong Vue.js
Computed là một trong những khái niệm căn bản và sử dụng nhiều nhất, là trung tâm xử lý dữ liệu của một Vue instance. Hôm nay chúng ta cùng đi tìm hiểu về Computed trong Vue.js.
Khái niệm
Computed hay Computed property là nơi xử lý dữ liệu trên Vue.js, dữ liệu được xử lý lấy từ các thuộc tính trả về trong data hoặc một thuộc tính ràng buộc nào khác. Chính vì lấy dữ liệu trong data nên computed không nhận bất kỳ tham số nào truyền vào và bắt buộc phải trả về một giá trị.
<div>
{{ message.split('').reverse().join('') }}
</div>
Template cần đơn giản và mang tính khai báo (declarative). Ta sẽ phải mất chút thời gian thì mới nhận ra được message đã bị đảo ngược. Càng tệ hơn khi bạn sử dụng biến message đảo ngược này nhiều lần trong code.
Vậy nên, với bất kỳ đoạn logic phức tạp nào liên quan đến dữ liệu, hãy cho nó vào computed.
Áp dụng Computed property
Dưới đây là đoạn mã khi sử dụng computed property:
<template>
<h1>{{ reversedMessage }}</h1>
</template>
<script>
export default {
name: 'ShowMessage',
data(){
return {
message: "hững hờ mai thoảng gió đưa hương"
}
},
computed: {
reversedMessage() {
return this.message.split(' ').reverse().join(' ')
}
}
}
</script>
Trong ví dụ trên, reversedMessage được tạo ra để đảo ngược message ban đầu. Computed property luôn đảm bảo tính reactive trong Vue.js, mỗi khi dữ liệu đầu vào được thay đổi nó sẽ tự động cập nhật lại giá trị. Điểm hay nhất ở đây là chúng ta tạo ra được mối liên hệ giữa các thành phần phụ thuộc (dependency): các hàm getter của computed thì không bị hiệu ứng phụ (side effect), chính điều đó giúp dễ hiểu và dễ kiểm tra.
Ta cũng có thể đưa logic trên vào phần methods trong Vue.js như sau:
methods: {
reverseMessage: function () {
return this.message.split(' ').reverse().join(' ')
}
}
Mình sẽ đi chi tiết vào methods trong bài viết sau. Tuy vẫn có cùng kết quả so với computed property, tuy nhiên điều khác biệt mà chỉ computed property mới có đó chính là computed property được cache lại dựa vào những những thành phần phụ thuộc (dependency). Chỉ khi nào những thành phần phụ thuộc thay đổi nó mới cập nhật lại giá trị, truy cập tới computed reverseMessage sẽ ngay lập tức trả về kết quả được tính toán trước đó mà không phải chạy lại hàm một lần nữa. Chính vì thế, sử dụng computed sẽ làm tối ưu hiệu suất cho ứng dụng Vue.js của bạn.
Áp dụng vào bài toán hôm trước
“Chúng ta có danh sách một lượng lớn hoa quả, trong đó có trái cây từ Mỹ, từ Trung Quốc, và nhiều nơi khác, cả loại không rõ nguồn gốc. In ra màn hình danh sách trái cây có nguồn gốc và không từ Trung Quốc.”
fruits: [
{ name: 'Apple', origin: 'American' },
{ name: 'Pear', origin: 'China' },
{ name: 'Pineapple', origin: 'My Tho' },
{ name: 'Banana', origin: 'Ha noi' },
{ name: 'Orange', origin: 'China' },
{ name: 'Lemon', origin: 'Unknown' },
{ name: 'Watermelon', origin: 'Laos' }
]
Solution kỳ trước:
<template>
<div>
<li v-for="fruit in fruits" :key="fruit.name"
v-if="fruit.origin !== 'China' && fruit.origin !== 'Unknown'">
{{ fruit.name }}: {{ fruit.origin }}
</li>
</div>
</template>
Khó hiểu và khá phức tạp đúng không nào. Phải dùng Computed thôi:
<template>
<div>
<li v-for="fruit in freshFruits" :key="fruit.name">
</li>
</div>
</template>
.....
computed: {
freshFruits() {
return this.fruits.filter(f => f.origin !== 'China' && f.origin !== 'Unknown')
}
}
Hẹn gặp lại các bạn trong blog sau về methods trong Vue.js.