天天看點

Vue - 偵聽器 watch 和計算屬性 computed

推薦:​​Vue彙總​​

Vue - 偵聽器 watch 和計算屬性 computed

代碼:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>computed</title>
    <script src="./js/vue.js"></script>
</head>
<body>
    <div id="div">
        {{firstName + " " + lastName}}
    </div>
</body>
</html>
<script>
    var vue = new Vue({
        el: '#div',
        data: {
            firstName: 'Li',
            lastName: 'Kaven'
        }
    })
</script>      

效果:

Vue - 偵聽器 watch 和計算屬性 computed

模闆内的表達式非常便利,但是設計它們的初衷是用于簡單運算的。在模闆中放入太多的邏輯會讓模闆過重且難以維護。

使用​

​methods​

​自定義方法進行改造:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>computed</title>
    <script src="./js/vue.js"></script>
</head>
<body>
    <div id="div">
        {{fullName()}}
    </div>
</body>
</html>
<script>
    var vue = new Vue({
        el: '#div',
        data: {
            firstName: 'Li',
            lastName: 'Kaven'
        },
        methods:{
            fullName(){
                return this.firstName + " " + this.lastName;
            }
        }
    })
</script>      

效果:

Vue - 偵聽器 watch 和計算屬性 computed

但這個還是不夠完美,每次渲染頁面時,這個方法都會被調用一次,這樣會造成性能的損失。

代碼:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>computed</title>
    <script src="./js/vue.js"></script>
</head>
<body>
    <div id="div">
        {{fullName()}}
        {{count}}
    </div>
</body>
</html>
<script>
    var vue = new Vue({
        el: '#div',
        data: {
            firstName: 'Li',
            lastName: 'Kaven',
            count: 1
        },
        methods:{
            fullName(){
                console.log('重新計算');
                return this.firstName + " " + this.lastName;
            }
        }
    })
</script>      

效果:

Vue - 偵聽器 watch 和計算屬性 computed

改變​

​count​

​​時,​

​fullName()​

​也會被調用一次。

Vue提供了一種通用的方式來觀察和響應Vue執行個體上的資料變動:偵聽屬性。當你有一些資料需要随着其它資料變動而變動時,可以使用 ​

​watch​

​。

使用​

​watch​

​進行改造:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>computed</title>
    <script src="./js/vue.js"></script>
</head>
<body>
    <div id="div">
        {{fullName}}
        {{count}}
    </div>
</body>
</html>
<script>
    var vue = new Vue({
        el: '#div',
        data: {
            firstName: 'Li',
            lastName: 'Kaven',
            fullName: 'Li Kaven',
            count: 1
        },
        watch:{
            firstName: function (val) {
                console.log('重新計算');
                this.fullName = val + " " + this.lastName;
            },
            lastName: function (val) {
                console.log('重新計算');
                this.fullName = this.firstName + " " + val;
            }
        }
    })
</script>      

效果:

Vue - 偵聽器 watch 和計算屬性 computed

但現在還不夠完美,這樣偵聽屬性太麻煩了,如果屬性比較多,就會很繁瑣。

接下來就使用計算屬性​

​computed​

​來進行改造:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>computed</title>
    <script src="./js/vue.js"></script>
</head>
<body>
    <div id="div">
        {{fullName}}
        {{count}}
    </div>
</body>
</html>
<script>
    var vue = new Vue({
        el: '#div',
        data: {
            firstName: 'Li',
            lastName: 'Kaven',
            count: 1
        },
        computed: {
            fullName: function () {
                console.log('重新計算');
                return this.firstName + " " +this.lastName;
            }
        }
    })
</script>      

效果:

Vue - 偵聽器 watch 和計算屬性 computed

這裡我們聲明了一個計算屬性​

​fullName​

​​。我們提供的函數将用作​

​property vue.fullName​

​​的 ​

​getter​

​ 函數。

你可以打開浏覽器的控制台,自行修改例子中的 ​

​vue​

​​。​

​vue.fullName​

​​ 的值始終取決于​

​vue.firstName​

​​和​

​vue.lastName​

​的值。

你可以像綁定普通 ​

​property​

​​ 一樣在模闆中綁定計算屬性。Vue知道​

​vue.fullName​

​​依賴于​

​vue.firstName​

​​和​

​vue.lastName​

​​,是以當​

​vue.firstName​

​​或​

​vue.lastName​

​​發生改變時,所有依賴​

​vue.fullName​

​​ 的綁定也會更新。而且最妙的是我們已經以聲明的方式建立了這種依賴關系:計算屬性的​

​getter​

​函數是沒有副作用的,這使它更易于測試和了解。計算屬性是基于它們的響應式依賴進行緩存的。隻在相關響應式依賴發生改變時它們才會重新求值

我們為什麼需要緩存?假設我們有一個性能開銷比較大的計算屬性 A,它需要周遊一個巨大的數組并做大量的計算。然後我們可能有其他的計算屬性依賴于 A。如果沒有緩存,我們将不可避免的多次執行 A 的 ​

​getter​

​!如果你不希望有緩存,請用方法來替代。

當你有一些資料需要随着其它資料變動而變動時,你很容易濫用 ​

​watch​

​​。然而,通常更好的做法是使用計算屬性而不是指令式的 ​

​watch​

​ 回調。

如果隻是偵聽屬性就可以使用 ​

​watch​

​。

計算屬性的 setter

代碼:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>computed</title>
    <script src="./js/vue.js"></script>
</head>
<body>
    <div id="div">
        {{fullName}}
        {{count}}
    </div>
</body>
</html>
<script>
    var vue = new Vue({
        el: '#div',
        data: {
            firstName: 'Li',
            lastName: 'Kaven',
            count: 1
        },
        computed: {
            fullName: {
                // getter
                get: function () {
                    return this.firstName + ' ' + this.lastName
                },
                // setter
                set: function (newValue) {
                    var names = newValue.split(' ')
                    this.firstName = names[0]
                    this.lastName = names[names.length - 1]
                }
            }
        }
    })
</script>      

效果:

Vue - 偵聽器 watch 和計算屬性 computed

​vue.fullName​

​​改變了,​

​vue.lastName​

​​也相應跟着變了(​

​vue.firstName​

​也是一樣)。

繼續閱讀