Computed trong vue js

Trước khi vào bài viết này nếu bạn chưa hiểu vuejs là gì hãy tham khảo kiến thức cơ bản về nó ở link sau:

Bắt đầu thôi!!

Chúng ta đã khá quen với việc viết các biểu thức ngay trong {{}} khi dùng vue. Nhưng việc này chỉ thực sự có ích khi sử dụng với những biểu thức đơn giản. Sẽ ra sao nếu bạn phải dùng đi dùng lại biểu thức đó hay đơn giản hơn là biểu thức cần xử lý phức tạp hơn???

để dễ hiểu hơn chúng ta hãy cùng làm một chiếc đồng hồ đếm thời gian nhé.

<script type="text/javascript" src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.3.4/vue.min.js" type="text/javascript"></script>
<div id="example">
  {{Math.trunc((now - startTime) / 60 / 60 / 24) | two_digits}}:{{Math.trunc((now - startTime) / 60 / 60) % 24 | two_digits}}:{{Math.trunc((now - startTime) / 60) % 60 | two_digits}}:{{(now - startTime) % 60 | two_digits}}<br>
</div>
<script>
    Vue.filter('two_digits', function (value) {
        if (value.toString().length <= 1) {
            return "0" + value.toString();
        }
        return value.toString();
    });
    var app = new Vue({
        data: function () {
            let tmp = Math.trunc((new Date()).getTime() / 1000);
            return {
                startTime: tmp,
                now: tmp,
            }
        },
        created: function () {
            let self = this;
            self.init();
        },
        methods: {
            init: function () {
                let self = this;
                self.interval = window.setInterval(() => {
                    self.now = Math.trunc((new Date()).getTime() / 1000);
                }, 1000);
            }
        },
        el: '#example',
    });

</script>

bạn có thể dễ dàng nhận ra rằng chúng ta cần phải biến những biểu thức kia thành một số hàm để tận dụng cũng như làm code của chúng ta dễ hiểu hơn.

<script type="text/javascript" src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.3.4/vue.min.js" type="text/javascript"></script>
<div id="example">
  {{fnDays() | two_digits}}:{{fnHours() | two_digits}}:{{fnMinutes() | two_digits}}:{{fnSeconds() | two_digits}}
</div>

<script>
    Vue.filter('two_digits', function (value) {
        if (value.toString().length <= 1) {
            return "0" + value.toString();
        }
        return value.toString();
    });
    var app = new Vue({
        data: function () {
            let tmp = Math.trunc((new Date()).getTime() / 1000);
            return {
                startTime: tmp,
                now: tmp,
            }
        },
        created: function () {
            let self = this;
            self.init();
        },
        methods: {
            init: function () {
                let self = this;
                self.interval = window.setInterval(() => {
                    self.now = Math.trunc((new Date()).getTime() / 1000);
                }, 1000);
            },
            fnSeconds() {
                return (this.now - this.startTime) % 60;
            },
            fnMinutes() {
                return Math.trunc((this.now - this.startTime) / 60) % 60;
            },
            fnHours() {
                return Math.trunc((this.now - this.startTime) / 60 / 60) % 24;
            },
            fnDays() {
                return Math.trunc((this.now - this.startTime) / 60 / 60 / 24);
            },
            fnNow(){
                return Math.trunc((new Date()).getTime() / 1000);
            }
        },
        el: '#example',
    });

</script>

đã xong. Mọi thứ có vẻ ngon nghẻ rồi. Nhưng liệu còn cách nào khác không? Tất nhiên vẫn còn rất nhiều cách khác. Một trong những cách đó chính là sử dụng computed property

<script type="text/javascript" src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.3.4/vue.min.js" type="text/javascript"></script>
<div id="example">
  {{days | two_digits}}:{{hours | two_digits}}:{{minutes | two_digits}}:{{seconds | two_digits}}<br>
  {{fnDays() | two_digits}}:{{fnHours() | two_digits}}:{{fnMinutes() | two_digits}}:{{fnSeconds() | two_digits}}<br>
</div>

<script>
    Vue.filter('two_digits', function (value) {
        if (value.toString().length <= 1) {
            return "0" + value.toString();
        }
        return value.toString();
    });
    var app = new Vue({
        data: function () {
            let tmp = Math.trunc((new Date()).getTime() / 1000);
            return {
                startTime: tmp,
                now: tmp,
            }
        },
        created: function () {
            let self = this;
            self.init();
        },
        computed: {
            seconds() {
                return (this.now - this.startTime) % 60;
            },
            minutes() {
                return Math.trunc((this.now - this.startTime) / 60) % 60;
            },
            hours() {
                return Math.trunc((this.now - this.startTime) / 60 / 60) % 24;
            },
            days() {
                return Math.trunc((this.now - this.startTime) / 60 / 60 / 24);
            }
        },
        methods: {
            init: function () {
                let self = this;
                self.interval = window.setInterval(() => {
                    self.now = Math.trunc((new Date()).getTime() / 1000);
                }, 1000);
            },
            fnSeconds() {
                return (this.now - this.startTime) % 60;
            },
            fnMinutes() {
                return Math.trunc((this.now - this.startTime) / 60) % 60;
            },
            fnHours() {
                return Math.trunc((this.now - this.startTime) / 60 / 60) % 24;
            },
            fnDays() {
                return Math.trunc((this.now - this.startTime) / 60 / 60 / 24);
            }
        },
        el: '#example',
    });

</script>

sau khi khai báo các function trong computed sẽ được sử dụng một cách dễ dàng như việc gọi một property.

Vậy Sự khác nhau giữa sử dụng computed và methods là gì ngoài cách gọi như một property của computed?

Tất nhiên phải có sự khác nhau thì vue mới đưa ra cho chúng ta 2 khái niệm đó. Sự khác nhau đó chính là computed property chỉ được thay đổi thi một trong các giá trí tính toán của nó thay đổi. Còn các hàm trong methods sẽ vẫn được gọi tính toán lại khi có sự update của các giá trị không nằm trong biểu thức tính toán của nó. Để dễ hiểu hơn chúng ta lại xem tiếp ví dụ:

<script type="text/javascript" src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.3.4/vue.min.js" type="text/javascript"></script>
<div id="example">
  {{cNow}} 
  {{fnNow()}} 
</div>

<script>
    var app = new Vue({
        data: function () {  
            return {
               now: null
            }
        },
        created: {
            let self = this;
            window.setInterval(() => {
                self.now = Math.trunc((new Date()).getTime() / 1000);
            }, 1000);
        },
        computed: {
            cNow() {
                return Math.trunc((new Date()).getTime() / 1000);
            }
        },
        methods: {
            fnNow(){
                return Math.trunc((new Date()).getTime() / 1000);
            }
        },
        el: '#example',
    });

</script>

Sau khi chay ví dụ trên bạn sẽ thấy gía trị in ra của fnNow() sẽ thay đổi còn của cNow là ko đổi.

Đôi khi dùng computed còn có lợi hơn cả việc dùng watch hãy cùng xem ví dụ sau:

<div id="example">{{ fullName }}</div>
var app = new Vue({
  el: '#example',
  data: {
    firstName: 'Cao',
    lastName: 'Thắng',
    fullName: 'Cao Thắng'
  },
  watch: {
    firstName: function (val) {
      this.fullName = val + ' ' + this.lastName
    },
    lastName: function (val) {
      this.fullName = this.firstName + ' ' + val
    }
  }
})
var app = new Vue({
  el: '#example',
  data: {
    firstName: 'Cao',
    lastName: 'Thắng'
  },
  computed: {
    fullName: function () {
      return this.firstName + ' ' + this.lastName
    }
  }
})

 

Add a Comment

Scroll Up