【Vue計算屬性】

咱們都知道在Vue構造函數的參數對象中有一個【data】屬性,該屬性值是一個對象,該對象是對數據的代理,是一個鍵值對而且時刻與頁面表現是一致的,可是這裏面只能是簡單的鍵值對,不能擁有業務邏輯,而且因爲【data】中的屬性屬於同一個生命週期,因此若是咱們須要某一個屬性是依賴於另一個屬性時,在【data】中是作不到的,因而Vue爲咱們提供了【計算屬性】es6


1、計算屬性

1.1 概述

計算屬性歸根結底也是屬性,它也是跟表現層是時刻同步的,雖然咱們能夠在插值中對數據進行各類處理,可是插值中的表達式處理畢竟只能用於簡單的運算,不能擁有太多的業務邏輯。數據庫

<body>
    <div id="app">
        <h1>{{name.toUpperCase()}}</h1>
        <!-- <h1>BLUE</h1> -->
    </div>
</body>

<script>
    let vm = new Vue({
        el: "#app",
        data: {
            name: 'blue'
        }
    })
</script>

上面代碼是咱們熟悉的在插值中使用表達式,可是這裏面咱們不能寫入業務代碼。數組

1.2 計算屬性語法

在構造函數的參數對象中有一個【computed】屬性,該屬性就是用於定義計算屬性的,該對象中的【鍵】也就是咱們的計算屬性,與【data】不一樣的是,計算屬性的鍵值是一個【擁有返回值的函數】,該函數中能夠訪問到【data】中的全部屬性。緩存

<body>
    <div id="app">
        <h1>{{rs}}</h1>
        <!-- <h1>BLUE LOVE PINK</h1> -->
    </div>
</body>

<script>
    let vm = new Vue({
        el: "#app",
        data: {
            hs: 'BLUE',
            wf: "PINK"
        },
        computed: {
            rs:function(){
                return `${this.hs} LOVE ${this.wf}`
            }
        }
    })
</script>

上面代碼屬性【rs】是定義的一個計算屬性,該屬性值是經過【data】中的兩個屬性值計算獲得,返回一個拼接的字符串(這兒使用了ES6的【模板字符串】)而且當【data】中的相關值變化以後,【rs】屬性都會進行從新計算。app

可能剛開始對計算屬性會有些疑惑,好比上面的例子我把代碼寫成下面這樣子也是能夠的異步

<body>
    <div id="app">
        <h1>{{hs}} LOVE {{wf}}</h1>
        <!-- <h1>BLUE LOVE PINK</h1> -->
    </div>
</body>

<script>
    let vm = new Vue({
        el: "#app",
        data: {
            hs: 'BLUE',
            wf: "PINK"
        }
    })
</script>

上面的代碼運行效果和咱們使用計算屬性的效果是同樣的,可是這樣的寫法只適用於簡單的處理,【計算屬性能夠處理更復雜的業務邏輯】,好比咱們根據【data】中的一個屬性值進行數據請求用於構建一個屬性,咱們就必須使用計算屬性了。函數

【注意!!】計算屬性雖然是一個方法,可是在Vue內部會被翻譯成一個屬性,咱們可使用實例【vm.rs】訪問到數據的。性能

1.3 計算屬性和過濾器的比較

若是用於對【data】中【單個】屬性的【簡單】處理,推薦使用過濾器,可是若是一個值使用了【data】中至少2個值或者對一個值進行復雜處理,那麼就推薦使用計算屬性了。this

<body>
    <div id="app">
        <h1>{{hs | lover}}</h1>
        <!-- <h1>BLUE LOVE PINK</h1> -->
    </div>
</body>

<script>
    let vm = new Vue({
        el: "#app",
        data: {
            hs: 'BLUE',
        },
        filters: {
            lover(value){
                return `${value} LOVE PINK`
            }
        }
    })
</script>

上面代碼就使用了一個【data】屬性值作簡單的處理,因此使用過濾器,並且也發現了過濾字符串「LOVE PINK」是不可變的。翻譯

1.4 計算屬性和Methods的比較

計算屬性就是爲了定屬性的時候處理複雜的業務邏輯,並且在插值中咱們可使用表達式,那麼咱們是否能夠經過使用在插值中調用一個有返回值的函數呢?它和計算屬性又有什麼區別呢?

<body>
    <div id="app">
        <h1>{{rs}}</h1>
        <!-- <h1>EULB</h1> -->
    </div>
</body>

<script>
    let vm = new Vue({
        el: "#app",
        data: {
            name: 'BLUE',
        },
        computed: {
            rs: function () {
                return [...this.name].reverse().join('');
            }
        }
    })
</script>

上面代碼將數據進行反向處理(使用了【ES6數組字符串擴展】),當咱們改變name的值的時候,計算屬性【rs】會跟着改變。下面咱們將它改爲一個方法結合插值表達式進行處理,看看區別。

<body>
    <div id="app">
        <h1>{{ rs() }}</h1>
        <!-- <h1>EULB</h1> -->
    </div>
</body>

<script>
    let vm = new Vue({
        el: "#app",
        data: {
            name: 'BLUE',
        },
        methods: {
            rs() {
                return [...this.name].reverse().join('');
            }
        }
    })
</script>

上面代碼將計算屬性改爲了一個方法結合插值表達式,發現效果和計算屬性沒差異,改變name的值的時候頁面也刷新了。那是否是這二者就真的沒區別呢,答案固然是否認的,若是沒有區別幹嗎還有計算屬性的存在。

【計算屬性是基於依賴進行緩存的】,只有計算屬性的依賴發生改變時纔會從新求值,也就是說若是依賴沒有發生改變,那麼計算屬性會馬上返回以前的計算結果,假如咱們有一個性能開銷比較大的的計算屬性 A ,它須要遍歷一個極大的數組和作大量的計算。而後咱們可能有其餘的計算屬性依賴於 A 。若是沒有緩存,咱們將不可避免的屢次執行 A 的 getter!若是你不但願有緩存,請用 method 替代。

1.5 計算屬性和Watch的比較

咱們發現計算屬性會監聽依賴,若是依賴發生變化則會重新計算屬性,那麼【監聽器】也有這麼一個功能,那麼咱們應該在何時使用【計算屬性】,何時使用【監聽器】呢?

<body>
    <div id="app">
        <h1>{{fullName}}</h1>
    </div>
</body>

<script>
    let vm = new Vue({
        el: "#app",
        data: {
            firstName: 'Jack',
            lastName: 'Blue',
            fullName: 'Jack Blue'
        },
        watch: {
            firstName: function (val) {
                this.fullName = val + ' ' + this.lastName
            },
            lastName: function (val) {
                this.fullName = this.firstName + ' ' + val
            }
        }
    })
</script>

上面代碼中咱們監聽firstName和lastName用於構建fullName,效果很好,當firstName和lastName任意一個值改變的時候fullName都會隨之改變。下面咱們看一下計算屬性的寫法

<body>
    <div id="app">
        <h1>{{fullName}}</h1>
        <!-- <h1>Jack Blue</h1> -->
    </div>
</body>

<script>
    let vm = new Vue({
        el: "#app",
        data: {
            firstName: 'Jack',
            lastName: 'Blue',
        },
        computed: {
            fullName() {
                return this.firstName + ' ' + this.lastName
            }
        }
    })
</script>

上面代碼使用計算屬性的方式進行了改造,fullName 依賴 firstName和 lastName 兩個屬性,當這兩個屬性任意一個發生變化,fullname都會從新進行計算。可是計算屬性是否是簡潔了不少呢!

【總結!!】當一個屬性須要依賴多個【data】中的屬性時,建議使用計算屬性,若是咱們不是對屬性進行操做,只是單純的依據【data】中的某個值變化後作一些【非屬性操做】時或者是在數據變化響應時,【執行異步操做或開銷較大的操做】(好比:將變化後的值存入數據庫,而不是改變其餘屬性)就使用Watch。

1.6 計算屬性的setter

上面咱們是使用的計算屬性都是用於對計算屬性的取值,計算屬性默認頁只給了【getter】,可是在須要的時候咱們能夠人爲的添加【setter】

<body>
    <div id="app">
        <h1>{{fullName}}</h1>
        <!-- <h1>Jack Blue</h1> -->
    </div>
</body>

<script>
    let vm = new Vue({
        el: "#app",
        data: {
            firstName: 'Jack',
            lastName: 'Blue',
        },
        computed: {
            fullName: {
                //getter
                get() {
                    return this.firstName + ' ' + this.lastName
                },
                //setter
                set(newValue) {
                    var names = newValue.split(' ')
                    this.firstName = names[0]
                    this.lastName = names[names.length - 1]
                }
            }
        }
    })
</script>

上面代碼定義了計算屬性的一個setter,注意當須要定義setter的時候語法上面是有區別的。

相關文章
相關標籤/搜索