Vue 從入門到進階之路(三)


之前的文章我們已經對 vue 有了初步認識,這篇文章我們通過一個例子說一下 vue 的方法 methods,計算屬性 computed 和監聽器 watch。

現在我們有一個需求,變量 firstName = "hello",變量 lastName = "world",我們需要將這兩個變量拼接到在前端展示,最基本的我們可以想到的就是:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>vue</title>
    <script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>
<body>
<div id="app">
    <p>{{firstName + " " + lastName}}</p>
    <p>{{firstName}} {{lastName}}</p>
</div>
<script>
    var app = new Vue({
        el: '#app',
        data: {
            firstName: 'hello',
            lastName: 'world',
        },
    })
</script>
</body>
</html>

以上兩種寫法很明顯是可以這么做的,但是第一種我們在 {{ }} 插值表達式內進行了代碼的計算,這是我們不建議使用方式,第二種是寫兩個 {{ }} 插值表達式,看起來效果不錯,但是如果我們要再拼接多個的話在 HTML 代碼中就顯得冗余了,后期也不好維護。接下來我們看一下如何在方法內實現:

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>vue</title>
 6     <script src="https://cdn.jsdelivr.net/npm/vue"></script>
 7 </head>
 8 <body>
 9 <div id="app">
10     <p>{{fullName()}} {{time}}</p>
11 </div>
12 <script>
13     var app = new Vue({
14         el: '#app',
15         data: {
16             firstName: 'hello',
17             lastName: 'world',
18             time: 1
19         },
20         methods:{
21             fullName(){
22                 console.log("計算了一次");
23                 return this.firstName + " " + this.lastName
24             }
25         }
26     })
27 </script>
28 </body>
29 </html>

上面的代碼我們在 methods 里定義了一個 fullName 的方法,然后通過 {{ }} 插值表達式放在 HTML 里,當頁面加載的時候直接調用,運行結果如下:

 

我們在頁面加載的時候同時定義了一個 time 的數據,當我們更新這個 time 數據的時候,結果如下:

我們發現當我們更新 time 數據的時候,fullName 方法也調用了一次。這顯然不是很理想的。

我們再來看一下利用監聽器 watch 方法:

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>vue</title>
 6     <script src="https://cdn.jsdelivr.net/npm/vue"></script>
 7 </head>
 8 <body>
 9 <div id="app">
10     <p>{{fullName}} {{time}}</p>
11 </div>
12 <script>
13     var app = new Vue({
14         el: '#app',
15         data: {
16             firstName: 'hello',
17             lastName: 'world',
18             fullName: 'hello world',
19             time: 1
20         },
21         watch: {
22             firstName() {
23                 console.log("firstName 更改了");
24                 this.fullName = this.firstName + " " + this.lastName;
25             },
26             lastName() {
27                 console.log("lastName 更改了");
28                 this.fullName = this.firstName + " " + this.lastName;
29             }
30         }
31     })
32 </script>
33 </body>
34 </html>

結果如下:

我們在 Vue 實例的 watch 屬性里定義了兩個方法 firstName 和 lastName,watch 屬性中方法名和 data 屬性里的數據變量名相同,表示會實時監聽該數據的變化,如果監聽到變化時會實時更新 DOM。

我們先來看一下當跟 methods 方法那樣更新 time 數據時的變化:

我們可以看出當 time 數據更新時並沒有調用 firstName 和 lastName 里的數據。當我們更新 firstName 和 lastName 的數據時,結果如下:

我們可以看出當我們更新 firstName 或者 lastName 的數據時,fullName 數據才會更新,這說明當數據掛載到 DOM 上的時候會緩存起來,如果數據不更新,則還會繼續使用緩存的數據,當數據更新時才會調用 watch 里面的方法,這就比 methods 的方法要好很多。

我們再來看一下計算屬性 computed:

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>vue</title>
 6     <script src="https://cdn.jsdelivr.net/npm/vue"></script>
 7 </head>
 8 <body>
 9 <div id="app">
10     <p>{{fullName}} {{time}}</p>
11 </div>
12 <script>
13     var app = new Vue({
14         el: '#app',
15         data: {
16             firstName: 'hello',
17             lastName: 'world',
18             time: 1
19         },
20         computed:{
21             fullName(){
22                 console.log("計算了一次");
23                 return this.firstName + " " + this.lastName;
24             }
25         }
26     })
27 </script>
28 </body>
29 </html>

運行結果如下:

 我們可以看出跟 watch 比,我們並沒有在 data 里定義 fullName 數據,而是在 computed 屬性里直接定義 fullName 然后 return 出 firstName 和 lastName 的拼接結果,當頁面呈現時,從輸出結果可以看出會走一次計算屬性,當我們改變 time 數據時:

可以看出 computed 里的方法沒有被調用,當我們改變 firstName 或者 lastName 的數據時,結果如下:

從上面的結果可以看出 computed 里面的方法被調用了,這是我們想要的結果,當跟 fullName 有關的 firstName 和 lastName 數據改變時計算屬性才會重新計算,當跟 fullName 無關的 time 數據變化時會用之前緩存的數據,這正是我們想要的結果。

 

以上三種方法進行比較我們可以得知 methods 方法是最不理想的,監聽器 watch 和 計算屬性 computed 兩種方法的運行結果是一樣的,但是 計算屬性 computed 方法更簡單一些。所以在 watch 和 computed 兩種方法都能實現的時候我們更推薦使用 computed 方法。

 

但是上面的 watch 和 computed 兩個方法里有個問題,就是 watch 里我們在 data 里定義了一個 fullName 的數據,當我們在更改 fullName 的值時 DOM 會跟着改變,這個跟 firstName 和 lastName 數據更改是一樣的。但是當我們在 computed 里我們並沒有定義 fullName,當我們更改 fullName 的數據時,如下:

我們發現 DOM 並沒有更新,這跟 watch 比起來就顯得不友好了,其實在 computed 里有 get 和 set 兩個屬性,我們 computed 的 fullName 方法改成如下:

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>vue</title>
 6     <script src="https://cdn.jsdelivr.net/npm/vue"></script>
 7 </head>
 8 <body>
 9 <div id="app">
10     <p>{{fullName}} {{time}}</p>
11 </div>
12 <script>
13     var app = new Vue({
14         el: '#app',
15         data: {
16             firstName: 'hello',
17             lastName: 'world',
18             time: 1
19         },
20         computed: {
21             fullName: {
22                 get() {
23                     console.log("計算了一次");
24                     return this.firstName + " " + this.lastName;
25                 },
26                 set(value) {
27                     console.log(value);
28                     var result = value.split(" ");
29                     this.firstName = result[0];
30                     this.lastName = result[1];
31                 }
32 
33             }
34         }
35     })
36 </script>
37 </body>
38 </html>

運行結果如下:

可以看出當我們通過 get 和 set 就可以改變 fullName 的值使 DOM 更新了。當頁面更新的時候先觸發 fullName 中的 get 方法,並返回 fullName,當我們改變 time 時,fullName 所依賴的 firstName 和 lastName 並沒有更改,所以就 fullName 就會去取緩存的值,在 fullName 的 set 方法里可以傳一個 value 的參數,通過打印我們可以看出 value 值就是我們直接改變 fullName 的值,我們就可以通過該值來賦值改變 firstName 和 lastName,這樣 fullName 所依賴的 firstName 或 lastName 改變時 DOM 就會實時更新了。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM