1. 程式人生 > 實用技巧 >vue計算屬性和監聽器

vue計算屬性和監聽器

計算屬性 computed

computed 選項定義計算屬性。
計算屬性類似於 methods 選項中的函式。

比較:

  • 計算屬性:會進行快取,只在相關響應式依賴發生改變的時候才會重新求值。
  • 函式:每次都會執行函式體進行計算。

需求:輸入數學與英語的分數,採用 methods 與 computed 分別計算出總得分。

使用函式

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>計算屬性和監聽器</title>
</head>

<body>
    <div id="app">
        數學:<input type="text" v-model="mathScore">
        英語:<input type="text" v-model="englishScore">
        <!-- v-model呼叫函式時不要少了小括號() -->
        總得分:<input type="text" v-model="sumScore()">
    </div>
    <script src="./node_modules/vue/dist/vue.js"></script>
    <script>
        var vm = new Vue({
            el: '#app',
            data: {
                mathScore: 80,
                englishScore: 90,
            },
            methods: {
                sumScore: function () {
                    console.log("sumScore函式被呼叫了。。。")
                    // this 指向的是vm例項
                    // 減0是為了字串轉為數字運算
                    return (this.mathScore - 0) + (this.englishScore - 0)
                },
            },
        })
    </script>
</body>

</html>

使用計算屬性

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>計算屬性和監聽器</title>
</head>

<body>
    <div id="app">
        數學:<input type="text" v-model="mathScore">
        英語:<input type="text" v-model="englishScore">
        <!-- v-model呼叫函式時不要少了小括號() -->
        總得分(函式):<input type="text" v-model="sumScore()">
        <!-- 計算屬性後面不需要加小括號 -->
        總得分(計算屬性):<input type="text" v-model="sumScore1">
    </div>
    <script src="./node_modules/vue/dist/vue.js"></script>
    <script>
        /**
         * 1. 函式沒有快取,每次都會呼叫。
         * 2. 計算屬性有快取,只有當計算屬性體內的屬性值發生改變之後才會被呼叫。
         * 3. 函式只支援單項的。
         * 4. 計算屬性預設只有getter函式,而沒有setter函式,所以只支援單項。
         *      如果想要進行雙向,則需要自定義setter函式。
         */
        var vm = new Vue({
            el: '#app',
            data: {
                mathScore: 80,
                englishScore: 90,
            },
            // 函式
            methods: {
                sumScore: function () {
                    console.log("sumScore函式被呼叫了。。。")
                    // this 指向的是vm例項
                    // 減0是為了字串轉為數字運算
                    return (this.mathScore - 0) + (this.englishScore - 0)
                },
            },
            // 計算屬性
            computed: {
                sumScore1:function(){
                    // 計算屬性有快取,如果計算屬性體內的屬性值沒有發生改變,則不會發生改變,只要屬性值發生改變的時候才會重新計算。
                    console.log("計算屬性被呼叫")
                    return (this.mathScore - 0) + (this.englishScore - 0)
                }
            },
        })
    </script>
</body>

</html>

  1. 函式沒有快取,每次都會呼叫。
  2. 計算屬性有快取,只有當計算屬性體內的屬性值發生改變之後才會被呼叫。
  3. 函式只支援單項的。
  4. 計算屬性預設只有getter函式,而沒有setter函式,所以只支援單項。如果想要進行雙向,則需要自定義setter函式。

計算屬性(雙向繫結)

計算屬性預設只有getter,不過在需要的時候你也可以提供一個setter。

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>計算屬性和監聽器</title>
</head>

<body>
    <div id="app">
        數學:<input type="text" v-model="mathScore"><br>
        英語:<input type="text" v-model="englishScore"><br>
        <!-- v-model呼叫函式時不要少了小括號() -->
        總得分(函式-單項繫結):<input type="text" v-model="sumScore()"><br>
        <!-- 計算屬性後面不需要加小括號 -->
        總得分(計算屬性-單項繫結):<input type="text" v-model="sumScore1"><br>
        總得分(計算屬性-雙向繫結):<input type="text" v-model="sumScore2"><br>
    </div>
    <script src="./node_modules/vue/dist/vue.js"></script>
    <script>
        /**
         * 1. 函式沒有快取,每次都會呼叫。
         * 2. 計算屬性有快取,只有當計算屬性體內的屬性值發生改變之後才會被呼叫。
         * 3. 函式只支援單項的。
         * 4. 計算屬性預設只有getter函式,而沒有setter函式,所以只支援單項。
         *      如果想要進行雙向,則需要自定義setter函式。
         */
        var vm = new Vue({
            el: '#app',
            data: {
                mathScore: 80,
                englishScore: 90,
            },
            // 函式
            methods: {
                sumScore: function () {
                    console.log("sumScore函式被呼叫了。。。")
                    // this 指向的是vm例項
                    // 減0是為了字串轉為數字運算
                    return (this.mathScore - 0) + (this.englishScore - 0)
                },
            },
            // 計算屬性
            computed: {
                // 這個是單項繫結,預設只有getter方法。
                sumScore1:function(){
                    // 計算屬性有快取,如果計算屬性體內的屬性值沒有發生改變,則不會發生改變,只要屬性值發生改變的時候才會重新計算。
                    console.log("計算屬性被呼叫")
                    return (this.mathScore - 0) + (this.englishScore - 0)
                },

                sumScore2:{ // 有了set和get之後就可以進行雙向資料繫結
                    // 獲取資料
                    get:function(){
                        console.log("sumScore2.get 計算屬性被呼叫")
                        return (this.mathScore - 0) + (this.englishScore - 0)
                    },
                    // 設定資料
                    set:function(newValue){ // newValue 是 sumScore2 更新之後的新值。
                        // 當 sumScore2 這個計算屬性值發生改變之後,則會呼叫這個方法。
                        console.log("sumScore2.set 計算屬性被呼叫")
                        var avgValue = newValue / 2
                        this.mathScore = avgValue
                        this.englishScore = avgValue
                    }
                }
            },
        })
    </script>
</body>

</html>

監聽器 watch

當屬性資料發生變化的時候,對應屬性的回撥函式會自動呼叫,在函式內部進行計算。

通過 watch 選項或者是 vm 例項的 $watch 來監聽指定的屬性。

需求:

  1. 通過 watch() 選項來監聽數學分數,當數學分數更新後回撥函式中重新計算總分。
  2. 通過 $watch() 來監聽英語分數,當英語更新後重新計算總分數。