GIỚI THIỆU
CĂN BẢN
NÂNG CAO
CÁC CHỦ ĐỀ
BÀI MỚI NHẤT
MỚI CẬP NHẬT

VueJS2: Computed Properties

Computed Properties dịch sang tiếng Việt rất khó hiểu nên mình sẽ dùng từ này như là một thuật ngữ trong VueJS luôn nhé. Tuy nhiên bạn có thể hiểu nôm na rằng Computed Properties là những hàm (methods) sử dụng để xử lý dữ liệu hiển thị lên template, kết quả của nó sẽ được lưu trữ (Cache) và chỉ cập nhật khi cần thiết. Ngoài ra ta cũng có thể xem computed là những phương thức setter và getter dùng để thiết lập dữ liệu và lấy dữ liệu đưa ra template.

test php

banquyen png
Bài viết này được đăng tại freetuts.net, không được copy dưới mọi hình thức.

1. Computed Properties

Chúng ta có rất nhiều cách để hiển thị dữ liệu ra View như: Sử dụng expression, sử dụng filters, sử dụng các directly binding (xem bài template syntax). Ngoài các cách đó ra thì chúng ta cũng có thể sử dụng computed properties để xử lý hiển thị dữ liệu hoặc thiết lập giá trị dữ liệu trong model.

Các expression ở trong template rất là tiện lợi, tuy nhiên nó chỉ tiện cho các phép toán đơn giản, nếu bạn gặp phải những phép toán phức tạp thì nhìn vào template của bạn sẽ cồng kềnh và khó hiểu.

Ví dụ: Hiển thị đảo ngược giá trị của message, đây là ví dụ khá hay từ trang chủ của VueJS thể hiện sự rườm rà khi sử dụng expression quá phức tạp trong template.

Code RUN
<div id="example">
    <p>Giá trị ban đầu: "{{ message }}"</p>
    <p>Giá trị sau khi chuyển đổi: "{{ message.split('').reverse().join('') }}"</p>
</div>
<script language="javascript">
    var vm = new Vue({
        el: '#example',
        data: {
            message: 'Chào mừng đến với freetuts.net'
        }
    });
</script>

Nhưng nếu chúng ta sử dụng Computed thì nhìn sẽ dễ dàng hơn.

Code RUN
<div id="example">
    <p>Giá trị ban đầu: "{{ message }}"</p>
    <p>Giá trị sau khi chuyển đổi: "{{ reverseMessage }}"</p>
</div>
<script language="javascript">
    var vm = new Vue({
        el: '#example',
        data: {
            message: 'Chào mừng đến với freetuts.net'
        },
        computed : {
            reverseMessage : function(){
                return this.message.split('').reverse().join('');
            }
        }
    });
</script>

Như vậy tất cả các computed sẽ được đặt trong key computed nhé các bạn, giống như mọi data ta đều đặt trong key data.

2. Computed và Methods

Như ở ví dụ trên ta hoàn toàn có thể thay thế computed bằng methods như sau:

Code RUN
<div id="example">
    <p>Giá trị ban đầu: "{{ message }}"</p>
    <p>Giá trị sau khi chuyển đổi: "{{ reverseMessage() }}"</p>
</div>
<script language="javascript">
    var vm = new Vue({
        el: '#example',
        data: {
            message: 'Chào mừng đến với freetuts.net'
        },
        methods : {
            reverseMessage : function(){
                return this.message.split('').reverse().join('');
            }
        }
    });
</script>

Kết quả cũng không có gì khác nhau, vậy tại sao chúng ta lại dùng computed thay vì dùng methods? Câu trả lời sẽ phụ thuộc vào ý đồ của bạn. Như ở bài methods mình có trình bày đặc điểm chung của nó đó là không được cached, vì vậy mỗi khi bạn gọi một method thì nó sẽ tính toán lại từ đầu. Còn đối với computed thì khác, kết quả của các computed sẽ được cached và chỉ cập nhật khi dư liệu thay đổi.

Giả sử mình có chương trình như sau, đây là chương trình chuyển từ số thành chữ:

Code RUN
<div id="example">
    <p>Number: "{{ number }}"</p>
    <p>Number To Word: "{{ showNumberWord }}"</p>
</div>

<script language="javascript">
    var vm = new Vue({
        el: '#example',
        data: {
            number : "12345"
        },
        computed : {
            showNumberWord : function(){
                console.log("Có gọi");
                var message = "";
                for (var i = 0; i < this.number.length; i++){
                    if (this.number[i] == "1"){
                        message += "Một ";
                    }
                    else if (this.number[i] == "2"){
                        message += "Hai ";
                    }
                    else if (this.number[i] == "3"){
                        message += "Ba ";
                    }
                    else if (this.number[i] == "4"){
                        message += "Bốn ";
                    }
                    else if (this.number[i] == "5"){
                        message += "Năm ";
                    }
                    else if (this.number[i] == "6"){
                        message += "Sáu ";
                    }
                    else if (this.number[i] == "7"){
                        message += "Bảy ";
                    }
                    else if (this.number[i] == "8"){
                        message += "Tám ";
                    }
                    else if (this.number[i] == "9"){
                        message += "Chín ";
                    }
                    else if (this.number[i] == "0"){
                        message += "Không ";
                    }
                } 
                return message;
            }
        }
    });
</script>

Bạn chú ý là mình có bổ sung đoạn code console.log("Có gọi"); để kiểm tra là computed đó sẽ được gọi bao nhiêu lần. Bây giờ mình sẽ sửa lại ở template như sau:

Code
<div id="example">
    <p>Number: "{{ number }}"</p>
    <p>Number To Word: "{{ showNumberWord }}"</p>
    <p>Number To Word: "{{ showNumberWord }}"</p>
</div>

Nếu theo đúng nguyên tắc của methods thì sẽ có hai tin thông báo "Có gọi", tuy nhiên do đây là một computed nên kết quả ở lần gọi thứ hai được cached nên không có xuất hiện thông báo đó (bạn hãy sử dụng console.log để xem nhé).

computed properties 01 png

3. Computed setter và getter

Mặc định mỗi computed sẽ có hai phương thức đó là getter setter, nếu bạn không khai báo thì mặc định nó sẽ hiểu là bạn đang sử dụng getter, vì vậy cuối mỗi computed luôn có lệnh return.

Getter mặc định

Code RUN
<div id="example">
    <p>Message: "{{ message }}"</p>
    <p>Uppercase Message: "{{ uppercaseMessage }}"</p>
</div>

<script language="javascript">
    var vm = new Vue({
        el: '#example',
        data: {
            message : "Học VueJS tại freetuts.net"
        },
        computed : {
            uppercaseMessage : function(){ 
                // mặc định Vue sẽ hiểu đây là getter nên phải có return
                return "[ " + this.message.toUpperCase() + " ]";
            }
        }
    });
</script>

Khai báo getter

Hoặc bạn cũng có thể sử dụng cú pháp khai báo getter như sau (kết quả bên template cũng không có gì thay đổi):

Code
var vm = new Vue({
    el: '#example',
    data: {
        message : "Học VueJS tại freetuts.net"
    },
    computed : {
        uppercaseMessage : {
            // Khai báo getter
            get : function(){
                return "[ " + this.message.toUpperCase() + " ]";
            }
        }
    }
});

Khai báo setter

Nếu bạn muốn khai báo setter thì viết như sau:

Code
var vm = new Vue({
    el: '#example',
    data: {
        message : "Học VueJS tại freetuts.net"
    },
    computed : {
        uppercaseMessage : {
            // Khai báo getter
            get : function(){
                return "[ " + this.message.toUpperCase() + " ]";
            },

            // Khai báo setter
            set : function(newValue){
                this.message = newValue.toLowerCase();
            }
        }
    }
});

// Mỗi khi ta thiết lập giá trị cho uppercaseMessage thì message sẽ bị thay đổi
// vì nội dung của hàm setter là this.message = newValue.toLowerCase();
vm.uppercaseMessage = "NGUYỄN VAN CƯỜNG";

console.log(vm.message); // nguyễn van cường

Bạn chú ý phần này nhé vì nó hơi khó hiểu. Mỗi khi bạn chạy vm.uppercaseMessage = "giá trị mới"; thì hàm setter sẽ được gọi nên giá trị của message cũng thay đổi theo.

4. Lời kết

Computer khá hay phải không các bạn. Chủ yếu trong bài này bạn phải phân biệt được khi nào thì dùng computed và khi nào thì dùng methods như sau: Nếu một chức năng bạn muốn mỗi khi gọi nó sẽ chạy lại từ đầu thì bạn sẽ dùng methods, còn bạn muốn không cần chạy lại cho tới khi dữ liệu bị thay đổi thì hãy dùng computed.

Cùng chuyên mục:

VueJS 2: Conditional Rendering (v-if và v-show)

VueJS 2: Conditional Rendering (v-if và v-show)

Trong bài này chúng ta sẽ tìm hiểu một số directive có nhiệm vụ xử…

VueJS 2: Binding Class và Binding Style

VueJS 2: Binding Class và Binding Style

Trong bài này chúng ta sẽ tìm hiểu cơ chế ràng buộc dữ liệu (binding…

VueJS 2: Tìm hiểu Watchers

VueJS 2: Tìm hiểu Watchers

Trong bài này chúng ta sẽ tìm hiểu về Vue Watcher, đây là cách để…

VueJS 2: Tìm hiểu Methods

VueJS 2: Tìm hiểu Methods

Methods không còn xa lạ với nhưng bạn đã từng tìm hiểu qua lập trình…

VueJS 2: Template Syntax

VueJS 2: Template Syntax

Giống như những thư viện Javascript khác, việc xử lý template chủ yếu dựa vào…

VueJS 2: Tìm hiểu Vue Instance

VueJS 2: Tìm hiểu Vue Instance

Instance trong lập trình chính là thể hiện của một lớp. Ví dụ nếu bạn…

VueJS 2: Cài đặt VueJS và viết chương trình Hello World

VueJS 2: Cài đặt VueJS và viết chương trình Hello World

Trong bài này mình sẽ cùng các bạn tìm hiểu cách cài đặt và viết…

VueJS là gì?

VueJS là gì?

Hôm nay chúng ta lại tiếp tục tìm hiểu một thư viện Javascript mới, hay…

Top