Vue 的 computed、methods 跟 watch 差在哪裡?(上)


Posted by Kai on 2020-11-02

相信有在寫 Vue 的一定對下面的程式碼不陌生

<div id="app">
    {{ message }}
</div>
<script>
    new Vue({
        el: '#app',
        data: {
            message: 'Hello'
        }
    })
</script>

這樣就會在畫面上呈現出,message 所代表的 Hello,而在 {{}} 中,我們是可以直接在上面使用 JavaScript 的方法,像是 split(), join(), splice() 等,來改變資料呈現的樣式,所以當我們需要的資料格式與原有的不符,我們就可以做出調整。像是透過 {{ message.split('').reverse().join('') }} 就可以在畫面上得到顛倒過來的 olleH。但這樣一來,程式碼看起來可讀性較差,而且也比較不容易維護,這時候就會需要用到 Vue 當中的計算屬性 (computed),大部分會以資料驅動資料的方式進行。
寫法如下:

<div id="app">
    {{ reversedmessage }}
</div>
<script>
    new Vue({
        el: '#app',
        data: {
            message: 'Hello'
        },
        computed: {
            reversedMessage: function () {
                return this.message.split('').reverse().join('')
            }
        }
    })
</script>

這樣一來,就可以順利在畫面呈現想要的資料了,但這樣的寫法和我們一般拿來放函式的 methods 有什麼差別呢?
以下的程式碼在畫面上會呈現相同的資料:

<div id="app">
    {{ reversedmessage }}
    {{ reversedmessage1() }}
</div>
<script>
    new Vue({
        el: '#app',
        data: {
            message: 'Hello'
        },
        computed: {
            reversedMessage: function () {
                return this.message.split('').reverse().join('')
            }
        },
        methods: {
            reversedMessage1: function () {
                return this.message.split('').reverse().join('')
        }
    }),
</script>

與 methods 的差異


  1. methods 呼叫時,由於是 function 形式,所以需要呼叫,才能呈現出資料。
  2. computed 有一個 caching 的功能,假如函式中所相依的資料被改變,computed 才會更新,而 methods 則是無論如何都會執行。

    在上面這段程式碼可以看到,當程式剛開始執行時,computedmethods 都會執行,但當我們呼叫時,因為相依的資料 (message) 沒有改變,因此 computed 中的 console.log('computed') 沒有再一次執行,會將之前處理過的資料回傳。

等等,為什麼 methods 也一起動了?


改變 data 中的資料時,依照先前所說的,應該會只有 computed 的部份會跟著連動,但 methods 的部分卻也一起更新,這是為什麼呢?

連動到底是連動什麼呢?


當在 methodscomputed 中個別加入一個使用到 message 資料的函式並改變資料,這時候會發現依然只有原先的兩個函式被呼叫了。也就是說,只有影響到畫面上資料呈現的部分,才會受到影響,也就是資料改變導致了畫面重新載入,所以不管是 computedmethods 只要和畫面上的資料有關,就會一起被連動


所以,當我們將呈現資料的部分註解掉後,再改變資料,這樣一來,不管是 methodscomputed 只要不在畫面上就不會執行。這裡需要注意的部分是,display: none;v-show 因為 Dom 存在所以同樣是在畫面上所以會執行,但假如使用 v-if 就不會有效果。

但是,Vue.js devtools 有顯示資料欸?

而這是因為,Vue.js devtools 為了顯示內容,會強制執行這些函式,就算目前並沒有使用到。

下一篇則會說到 Vue 中的 watch

資料來源:Alex 宅幹嘛


#Vue #Computed







Related Posts

React Styled-component 筆記 P1

React Styled-component 筆記 P1

AI輔導室|製作管狀字

AI輔導室|製作管狀字

用C++做資料分析 | CERN ROOT 教學[02] - 資料匯入與簡單分析

用C++做資料分析 | CERN ROOT 教學[02] - 資料匯入與簡單分析


Comments