Vue.js 計算屬性 計算屬性關鍵詞: computed。 計算屬性在處理一些複雜邏輯時是很有用的。 可以看下以下反轉字元串的例子: <template> <div id="app"> <p>{{info}}</p> <p>{{reverse}}</p> </div> </template> <s ...
Vue.js 計算屬性
計算屬性關鍵詞: computed。
計算屬性在處理一些複雜邏輯時是很有用的。
可以看下以下反轉字元串的例子:
<template> <div id="app"> <p>{{info}}</p> <p>{{reverse}}</p> </div> </template> <script> export default { name: 'App', data(){ return{ info:'califonia' } }, computed:{ reverse(){ return this.info.split('').reverse().join(''); } } } </script> <style scoped> </style>
computed vs methods 我們可以使用 methods 來替代 computed,效果上兩個都是一樣的,但是 computed 是基於它的依賴緩存,只有相關依賴發生改變時才會重新取值。而使用 methods ,在重新渲染的時候,函數總會重新調用執行。 可以說使用 computed 性能會更好,但是如果你不希望緩存,你可以使用 methods 屬性。 computed 屬性預設只有 getter ,不過在需要時你也可以提供一個 setter 在使用 reversedMessage 這個計算屬性的時候,第一次會執行代碼,得到一個值,以後再使用 reversedMessage 這個計算屬性,因為 vm 對象沒有發生改變,於是界面渲染就直接用這個值,不再重覆執行代碼。而 reversedMessage2 沒有這個緩存,只要用一次,函數代碼就執行一次,於是每次返回值都不一樣。
<template> <div id="app"> <p>{{info}}</p> computed計算,不需要加() <p>第一次:{{reverse1}}</p> <p>第二次:{{reverse1}}</p> methods方法,需要加() <p>第一次:{{reverse2()}}</p> <p>第二次:{{reverse2()}}</p> </div> </template> <script> var count=1; export default { name: 'App', data(){ return{ info:'baidu' } }, computed:{ reverse1(){ count+=1; return count+this.info.split('').reverse().join(''); } }, methods:{ reverse2(){ count+=1; return count+this.info.split('').reverse().join(''); } } } </script> <style scoped> </style>
當你沒有使用到計算屬性的依賴緩存的時候,可以使用定義方法來代替計算屬性,在 methods 里定義一個方法可以實現相同的效果,甚至該方法還可以接受參數,使用起來更靈活。
在vue.js中,有methods和computed兩種方式來動態當作方法來用的。
- 1.首先最明顯的不同 就是調用的時候,methods要加上()
- 2.我們可以使用 methods 來替代 computed,效果上兩個都是一樣的,但是 computed 是基於它的依賴緩存,只有相關依賴發生改變時才會重新取值。
而使用 methods ,在重新渲染的時候,函數總會重新調用執行。
Vue.js 監聽屬性
可以通過 watch 來響應數據的變化。
以下實例通過使用 watch 實現計數器:
<template> <div id="app"> <p>{{count}}</p> <button @click="count++">click me</button> </div> </template> <script> var count=1; export default { name: 'App', data(){ return{ count:1 } }, watch:{ count(nVal,oVal){ console.log('oldValue: '+nVal+' newValue: '+oVal); } } } </script> <style scoped> </style>
以下實例進行千米與米之間的換算:
<template> <div id="app"> kilometers: <input type="text" v-model="kilometers"> <br> meters: <input type="text" v-model="meters"> </div> </template> <script> var count=1; export default { name: 'App', data(){ return{ kilometers:0, meters:0 } }, watch:{ kilometers(val){ this.kilometers=val; this.meters=val*1000; }, meters(val){ this.meters=val; this.kilometers=val/1000; }, } } </script> <style scoped> </style>
模擬購物車效果
<template> <div id="app"> <table> <tr> <th>序號</th> <th>商品名</th> <th>價格</th> <th>數量</th> <th>操作</th> </tr> <tr v-for="item in list" :key="item.id"> <td>{{item.id}}</td> <td>{{item.name}}</td> <td>{{item.price}}</td> <td> <button v-bind:disabled="item.count===0" v-on:click="item.count--">-</button> {{item.count}} <button v-on:click="item.count++">+</button> </td> <td><button v-on:click="item.count=0">移除</button></td> </tr> </table> <p>總價:{{total()}}</p> </div> </template> <script> var count=1; export default { name: 'App', data(){ return{ list:[ { id:1, name:'iphone6', price:6000, count:1 }, { id:2, name:'iphone8', price:7000, count:1 }, { id:3, name:'iphonex', price:8000, count:1 } ] } }, methods:{ total(){ var totalPrice=0; for(var i=0;i<this.list.length;i++){ totalPrice+=this.list[i].price*this.list[i].count; } return totalPrice; } } } </script> <style scoped> table { border: 1px solid black; } table { width: 100%; } th { height: 50px; } th, td { border-bottom: 1px solid #ddd; } </style>
簡單的省市聯動
<template> <div id="app"> 省: <select v-model="province"> <option>請選擇</option> <option v-bind:value="p" v-for="p in provinces" :key="p">{{p}}</option> </select> 市: <select v-model="city"> <option>請選擇</option> <option v-bind:value="c" v-for="c in cityList" :key="c">{{c}}</option> </select> </div> </template> <script> var count=1; export default { name: 'App', data(){ return{ city: '請選擇', province: '請選擇', provinces: ['廣東', '湖南', '湖北', '北京'], cityList: [], area: [{ name: '廣東', id: 1, child: ['廣州', '深圳', '東莞'] }, { name: '湖南', id: 2, child: ['長沙', '株洲', '湘潭'] }, { name: '湖北', id: 3, child: ['武漢'] }, { name: '北京', id: 4, child: ['北京'] }] } }, watch:{ province(nVal,oVal){ if(nVal==='請選擇'){ this.cityList=[]; } if(nVal!==oVal){ for(var i=0;i<this.area.length;i++){ if(this.area[i].name===nVal){ this.cityList=this.area[i].child; } } } this.city='請選擇'; } } } </script> <style scoped> </style>