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.

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é).

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.

Nguồn: freetuts.net

KHÓA HỌC ĐANG GIẢM GIÁ

FEDU - 34- THỰC HÀNH THIẾT KẾ DỮ LIỆU VỚI SQL QUA BÀI TẬP

(Giảng viên: Nguyễn Đức Việt)

XEM
FEDU - 30 – HTML CSS cơ bản

(Giảng viên: Nguyễn Đức Việt)

XEM
FEDU - 029- Học lập trình React js và Redux từ đầu, tạo ứng dụng fullstack với Node JS + React JS

(Giảng viên: Nguyễn Đức Việt)

XEM
FEDU - 27 – Lập trình back-end cơ bản với nodejs & mongodb, mongooose, postgresql.

(Giảng viên: Nguyễn Đức Việt)

XEM
FEDU - 25 – Thiết kế hiệu ứng bằng Javascript và illustrator

(Giảng viên: NGUYỄN ĐỨC VIỆT )

XEM