VueJS

Computed in VueJS

Computed in VueJS

1. Computed trong VueJS là gì?

Khi mới làm việc với VueJS, chắc hẳn đã có bạn hỏi Computed là gì? Tại sao có Methods rồi lại còn cần đến Computed?
Thì câu trả lời như sau: Computed là để khi ta thao tác với Data có sẵn trong VueJS, các phương thức trong Computed được binding một chiều như thuộc tính trong Data properties. Mặc dù các phương thức trong Computed là hàm, nhưng chúng ta lại không thể truyền tham số vào vì Computed nó chỉ làm việc với data có sẵn.
Sau đây là một ví dụ:

<template>
    <div class="my-component">
        <div>Original message: "{{ message }}"</div>
        <div>Computed reversed message: "{{ reversedMessage }}"</div>
    </div>
</template>

<script>
    export default {
        data() {
            return {
                message: "Hello world!"
            }
        },
        computed: {
            reversedMessage() {
                return this.message.split('').reverse().join('');
            }
        }
    }
</script>

<style lang="scss" scoped>
    .my-component {
        color: rgb(40, 131, 104);
    }
</style>

Theo như trang chủ của VueJS, thì computed là giải pháp khi mới đầu ta làm việc với 1 một lượng data rất lớn, khi đó recommend là nên dùng computed. Còn trong trường hợp ta dùng Methods thì sẽ dẫn đến performance là không cao do các phương thức trong Methods sẽ vẫn chạy lại khi ta không thay đổi data.

2. Một số điều mà bạn có thể làm với Computed trong VueJS?

Như vậy 1 lần nữa, các nhà phát triền VueJS lại cho ta một công cụ rất hữu hiệu. Đối với các Computed properties ta cũng có thể gom nhóm chúng cho dễ quản lí hơn. Và khi App cũng chúng ta rất to, cần xử lí 1 lượng dữ liệu ban đầu là lớn thì Computed đúng là 1 trợ thủ đắc lực.
Và hãy nhớ kĩ 1 điều, là các phương thức trong Computed chỉ có thể chạy lại khi các thuộc tính mà nó xử lí return thay đổi và nó không chạy lại như method khi mà view thay đổi. Ví dụ như trong hợp dưới đây phương thức trong Computed sẽ không được chạy lại:

<script>
    export default {
        compoted: {
            now() {
                return Date.now();
            }
        }
    }
</script>

Hoặc như trong tường hợp nó không quan sát:

<template>
    <div class="my-component">
        <button @click="numberA++">Increase A</button>
        <button @click="numberA--">Decrease A</button>
        <button @click="numberB++">Increase B</button>
        <button @click="numberB--">Decrease B</button>
        <div>{{ numberA }} - {{ numberB }}</div>
        <div>{{ calculatute() }} - {{ calculatute_2 }}</div>
    </div>
</template>

<script>
    export default {
        data() {
            return {
                numberA: 0,
                numberB: 0
            }
        },
        methods: {
            calculatute() {
                console.log("methods");
                return this.numberA;
            }
        },
        computed: {
            calculatute_2() {
                console.log("compoted");
                return this.numberB;
            }
        }
    }
</script>

<style lang="scss" scoped>
    .my-component {
        color: rgb(40, 131, 104);
    }
</style>

Nếu ta chạy ví dụ trên, sẽ thấy chỉ khi thay đổi numberB thì Computed properties mới được chạy. ^^. This is so amazing.


Trong computed cũng có getter và setter để giúp ta phân tách những phần cần. Mặc định của các phương thức bên trong Computed sẽ là getter, nhưng nếu chúng ta muốn Computed properties bind 2 chiều, thì ta cần viết thêm setter cho nó.

Cụ thể với trường hợp mặc định thì 1 Computed properties sẽ chạy như sau:

<template>
    <div class="my-component">
    
        <input type="text" v-model="fullname" />
    
        <h1>{{firstName}}</h1>
    
        <h1>{{lastName}}</h1>
    
    </div>
</template>

<script>
export default {
    data() {
        return {
            firstName: "Terry",
            lastName: "Ben"
        }
    },
    computed: {
        fullname: {
            get: function() {
                return this.firstName + " " + this.lastName;
            }
        }
    }
}
</script>

<style lang="scss" scoped>
.my-component {
    color: rgb(40, 131, 104);
}
</style>

Đây là trường hợp mặc định, nếu ta cố tình update Computed properties này ở ngoài View khi đó ta sẽ nhận được 1 lỗi.
Computed property "fullname" was assigned to but it has no setter.

Để có thể fix được lỗi trên cũng như là làm cho Computed properties của Vue Binding 2 chiều thì ta sẽ viết thêm setter cho nó. ^^

<template>
    <div class="my-component">
    
        <input type="text" v-model="fullname" />
    
        <h1>{{firstName}}</h1>
    
        <h1>{{lastName}}</h1>
    
    </div>
</template>

<script>
export default {
    data() {
        return {
            firstName: "Terry",
            lastName: "Ben"
        }
    },
    computed: {
        fullname: {
            get: function() {
                return this.firstName + " " + this.lastName;
            },
            set : function(name) {
                const fname = name.split(" ");
                this.firstName = fname[0];
                this.lastName = fname[1]
            }
        }
    }
}
</script>

<style lang="scss" scoped>
.my-component {
    color: rgb(40, 131, 104);
}
</style>

Như vậy, ta đã không gặp lỗi như phía trên khi thay đổi input và cũng làm cho code của chúng ta uyển chuyển hơn khi không cần thêm 1 data properties là fullname.

3. Kết luận.

Cũng như methods, ta không nên dùng Arrow function ở trong Computed, vì nó sẽ không trỏ tới đối tượng VueJS mà ta muốn trỏ.
Trên đây là 1 chút hiểu của mình về Computed trong VueJS, nếu các bạn có thắc mắc gì hoặc có câu hỏi thì đừng ngại mà hãy comment xuống phía dưới nhé.

4. Tham khảo.

# Bài 5: Sử dụng computed trong VueJS, sự khác nhau giữa computed và methods
# Computed Properties and Watchers
# VueJS – Computed Properties

Tagged , , ,
0 0 vote
Article Rating
Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments