vue計算屬性和偵聽器


一、計算屬性:

main.js:

var app = new Vue({ el: '#app', data: { math: 80, physics: 90, english: 30 }, computed: { sum: function(){ return this.math + this.physics + this.english; }, average: function(){ return Math.round((this.math + this.physics + this.english)/3); } } });

index.html:

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="app"> <table border="1"> <thead> <td>學科</td> <td>分數</td> </thead> <tr> <td>數學</td> <td><input type="text" v-model.number="math"/></td> </tr> <tr> <td>物理</td> <td><input type="text" v-model.number="physics"/></td> </tr> <tr> <td>英語</td> <td><input type="text" v-model.number="english"/></td> </tr> <tr> <td>總分</td> <td>{{sum}}</td> </tr> <tr> <td>平均分</td> <td>{{average}}</td> </tr> </table> </div> <script src="../lib/vue.js"></script> <script src="./js/main.js"></script> </body> </html>

計算屬性有兩個特點:

1、只要計算屬性中利用到的屬性值發生改變它就會執行;

2、計算結果的值會緩存;

3、computed高級應用之:get、set

<p>{{fullName}}</p> <p><button v-on:click="changeName">change</button></p>
<script> var app = new Vue({ el: '#app', data: { firstName: "Samve", lastName: "Duan" }, computed: { fullName: { get: function(){ return this.firstName + " " + this.lastName; }, set: function(newValue){//給fullName賦值為newValue時執行 this.firstName = newValue.split(" ")[0]; this.lastName = newValue.split(" ")[1]; } } }, methods: { changeName: function(){ this.fullName = "xiao mi";//給計算屬性fullName賦值 } } }); </script>

computed應用場景:

對於模板標簽中任何復雜邏輯,你都應當使用計算屬性;

你可以像綁定普通屬性一樣在模板中綁定計算屬性。

二、偵聽器:

雖然計算屬性在大多數情況下更合適,但有時也需要一個自定義的偵聽器。這就是為什么 Vue 通過 watch 選項提供了一個更通用的方法,來響應數據的變化。當需要在數據變化時執行異步或開銷較大的操作時,這個方式是最有用的。

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link href="https://cdn.bootcss.com/bootstrap/4.1.1/css/bootstrap.css" rel="stylesheet"/> </head> <body> <div id="app"> <input type="text" v-model="user.name"/> <p>{{user.name}}</p> </div> <script src="https://cdn.bootcss.com/vue/2.5.17-beta.0/vue.js"></script> <script src="https://cdn.bootcss.com/vue-router/3.0.1/vue-router.js"></script> <script> let vm = new Vue({ el: '#app', data: { msg: 0, user: { id: 0, name: 'Samve' } }, watch: { msg: function(newMsg, oldMsg){ console.log('msg已被修改,newMsg:', newMsg, 'oldMsg:' + oldMsg); }, user: { handler: function(newValue, oldValue){ //handler默認執行函數,也可以去掉 console.log('user已經被修改,', newValue, oldValue); }, deep: true//表示監視對象的屬性變化,false則監視函數不執行,此時看不到newValue與oldValue的區別 //為了發現對象內部值的變化,可以在選項參數中指定deep:deep。注意:監聽數組的變動不需要這么做 //主要用於監聽屬性是對象的屬性變化 } } }) </script> </body> </html>

這其中有個問題,例如:

var vm=new Vue({ data:{ a:1, b:{ c:1 } }, watch:{ a(val, oldVal){//普通的watch監聽 console.log("a: "+val, oldVal); }, b:{//深度監聽,可監聽到對象、數組的變化 handler(val, oldVal){ console.log("b.c: "+val.c, oldVal.c);//但是這兩個值打印出來卻都是一樣的 }, deep:true } } }) vm.a=2 vm.b.c=2

a是一個普通的值,當a的值變化時會被監聽到,b是一個對象,不能直接像a那么寫,需要深度監聽才能捕捉到,但是當我想去捕捉b對象中某一個值的變化時卻發現,打印出來的兩個值是一樣的,如圖:

這樣就只能知道對象發生變化卻不知道具體哪個值發生了變化,如果想監聽對象某一個值得變化可以利用計算屬性computed

var vm=new Vue({ data:{ b:{ c:1 } }, watch:{ newValue(val, oldVal){ console.log("b.c: "+val, oldVal); } }, computed: {   newValue() {     return this.b.c   } } }) vm.b.c=2

用watch去監聽computed計算過的值就可以直接知道是哪個對應的值發生了變化,結果如圖: 

三、計算屬性的實際應用:

<script> var vm = new Vue({ el: '#computed_props', data: { kilometers : 0, meters:0 }, methods: { }, computed :{ }, watch : { kilometers:function(val) { this.kilometers = val; this.meters = val * 1000; }, meters : function (val) { this.kilometers = val/ 1000; this.meters = val; } } }); // $watch 是一個實例方法 vm.$watch('kilometers', function(newValue, oldValue){ // 這個回調將在 vm.kilometers 改變后調用 document.getElementById("info").innerHTML = "修改前值為: " + oldValue + ",修改后值為: " + newValue; }) </script>

 四、計算屬性與偵聽器的比較:

計算屬性顧名思義就是通過其他變量計算得來的另一個屬性,fullName在它所依賴firstName,lastName這兩個變量變化時重新計算自己的值。

另外,計算屬性具有緩存。計算屬性是基於它們的依賴進行緩存的。計算屬性只有在它的相關依賴發生改變時才會重新求值。這就意味着只要 lastName和firstName都沒有發生改變,多次訪問 fullName計算屬性會立即返回之前的計算結果,而不必再次執行函數。

而偵聽器watch是偵聽一個特定的值,當該值變化時執行特定的函數。例如分頁組件中,我們可以監聽當前頁碼,當頁碼變化時執行對應的獲取數據的函數。

①從屬性名上,computed是計算屬性,也就是依賴其它的屬性計算所得出最后的值。watch是去監聽一個值的變化,然后執行相對應的函數。

②從實現上,computed的值在getter執行后是會緩存的,只有在它依賴的屬性值改變之后,下一次獲取computed的值時才會重新調用對應的getter來計算。watch在每次監聽的值變化時,都會執行回調。其實從這一點來看,都是在依賴的值變化之后,去執行回調。很多功能本來就很多屬性都可以用,只不過有更適合的。如果一個值依賴多個屬性(多對一),用computed肯定是更加方便的。如果一個值變化后會引起一系列操作,或者一個值變化會引起一系列值的變化(一對多),用watch更加方便一些。
③watch的回調里面會傳入監聽屬性的新舊值,通過這兩個值可以做一些特定的操作。computed通常就是簡單的計算。

④watch和computed並沒有哪個更底層,watch內部調用的是vm.$watch,它們的共同之處就是每個定義的屬性都單獨建立了一個Watcher對象。

總結:

1.如果一個數據依賴於其他數據,那么把這個數據設計為computed的

2.如果你需要在某個數據變化時做一些事情,使用watch來觀察這個數據變化:watch屬性強調自身值得改變前后的動作,所以才有回調xxx(newVal,oldVal)

computed是用data已經申明的變量可以計算出來的另一個變量用來渲染頁面比較合適方便,而watch適合監聽某個data中的變量來操作一些邏輯行為比較合適,比如監聽某個變量改變然后發起異步請求。


免責聲明!

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



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