我們先來總結一下前面已經認識的選項
el:指定Vue實例的掛載點,根實例的特有屬性
data:用於聲明需要響應式綁定的數據對象
components:Vue實例配置局部註冊組件
template:用於掛載元素的字符串模板
render:渲染函數,創建虛擬DOM,是字符串模板的替代方案。
現在開始一個例子介紹一下其他常用的選項(options對象的屬性):
下面的代碼局部註冊了一個組件AgeStatistics,並把數據渲染到模板中
<div id="app">
<age-statistics inline-template>
<div>
<h1>**{{title}}</h1>
<table border="1">
<tr>
<th>編號</th><th>姓名</th><th>年齡</th>
</tr>
<tr v-for="(item,i) in list">
<td>{{i+1}}</td><td>{{item.name}}</td><td>{{item.age}} </td>
</tr>
</table>
<p>平均年齡:avg</p>
<div class="formGroup">
<input ref="name" type="text" v-model="currentPerson.name" placeholder="請填寫姓名">
<input ref="age" type="text" v-model="currentPerson.age" placeholder="請填寫年齡">
<button>添加</button>
</div>
</div>
</age-statistics>
</div>
<script src="./vue.js"></script>
<script>
let vm = new Vue({
el: "#app",
data:{
title:'三年五班'
},
components: {
'AgeStatistics':{
data() {
return {
title:'學員統計',
list:[
{name:'張三',age:18},
{name:'李四',age:19}
],
currentPerson:{}
}
}
}
}
});
</script>
methods:用於定義Vue實例的方法
methods選項是個對象,在其內部可以定義方法。
下面我們給button的click事件綁定一個方法add,組件的options種添加methods屬性,實現點擊按鈕時新增一條記錄
<button v-on:click="add">添加</button>
methods:{
add(e){
console.log(e);
console.log(event);
let _currentPerson = JSON.parse(JSON.stringify(this.currentPerson));
this.currentPerson={};
this.list.push(_currentPerson);
}
},
方法的參數
:
方法中可以獲得綁定的事件event,綁定事件方法時:
- 如果不包含(),默認的參數是event,即上面代碼中的e和event都指向事件對象;
- 如果包含(),參數e就是add傳遞的參數,如上面綁定的是add(),e即爲undefined。
computed:計算屬性
模板內的表達式可以用於簡單運算,對於複雜的計算應當使用實例的計算屬性computed
下面在computed中定義一個方法avg,顯示到平均年齡處
<p>平均年齡:{{avg}}</p>
//計算屬性
computed:{
avg(){
console.log('計算屬性avg執行了');
let sum=this.list.reduce((sum, data) => {
return sum + parseInt(data.age);
}, 0);
return sum/this.list.length
}
},
計算屬性對於從現有源組合新數據非常方便,與方法相比,它們的一大優點是緩存了輸出。
即:如果獨立於計算屬性的某些內容在頁面上發生更改,並且重新呈現UI。
computed中的方法會返回緩存的結果,不會重新計算;
methods中方法中會重新執行。
如在上例的methods增加一個方法avg2,來比較一下
<p>平均年齡:{{avg}}{{avg2()}}</p>
avg2(){
console.log('方法avg2執行了');
let sum=this.list.reduce((sum, data) => {
return sum + parseInt(data.age);
}, 0);
return sum/this.list.length
}
通過這個例子可以發現實現相同的功能methods中的方法代價更高。
另外你注意到了嗎,在模板中調用它們的方式也不一樣,在控制檯中,我們發現avg是個屬性,它的形式和data中的數據類似,但不擁有訪問器屬性get/set,而avg2是一個方法,所以avg2可以傳參;
但avg如果要傳參,需要使用閉包將屬性值改爲一個函數
<p>平均年齡:{{avg(2)}}</p>
computed:{
avg(){
return function (decimals) {
let sum=this.list.reduce((sum, data) => {
return sum + parseInt(data.age);
}, 0);
return sum/this.list.length.toFixed(decimals);
}
}
},
filters:過濾器
Vue.js 允許自定義過濾器,用於一些常見的文本格式化。
- 過濾器可以用在兩個地方:雙花括號插值和 v-bind 表達式 (後者從 2.1.0+ 開始支持)。
- 過濾器應該被添加在JS表達式的尾部,由“管道”符號連接。
- 過濾器函數始終以表達式的值作爲第一個參數。帶引號的參數視爲字符串,而不帶引號的參數按表達式計算。
- 模板中調用過濾器函數時如果使用了參數,順序稱爲過濾器函數的第二、三…個函數
- 可以添加多個過濾器
如前面的例子中,如果需要格式化平均年齡,保留一位小數點,可以這樣做:
<p>平均年齡:{{avg | formatAge(1,'something')}}</p>
//過濾器
filters:{
formatAge(val,decimals){
return val.toFixed(decimals);
}
},
也可以全局定義過濾器,定義的方法和全局註冊組件類似,要放到Vue實例化之前,如:
Vue.filter('formatAge', function (val) {
return val.toFixed(1);
})
watch:偵聽屬性
偵聽屬性watch的作用可以監控 Vue 實例上的數據變動,並調用其回調函數。
如:在watch中偵聽數據title和currentPerson的變化,一旦變化就執行回調,其回調函數有兩個參數,新值和舊值,如果偵聽的數據是數組或對象,新值和舊值打印的結果是一樣的。
watch: {
title(val, oldVal){
console.log(`監聽到了title的變化:${oldVal}->${val}`);
},
currentPerson(val, oldVal) {
console.log('監聽到了currentPerson的數據變動', val.age, oldVal.age);
},
}
handler方法和immediate屬性
watch 中的方法最初綁定的時候是不會執行,如果希望一開始就讓他最初綁定的時候就執行改怎麼辦呢?我們需要修改一下我們的 watch中title的監聽方法,修改過後的代碼如下:
/*title(val, oldVal){
console.log(`監聽到了title的變化:${oldVal}->${val}`);
},*/
title:{
handler(val, oldVal){
console.log(`監聽到了title的變化:${oldVal}->${val}`);
},
immediate:true
}
title綁定了一個handler方法,也就是設置回調函數,之前寫的 watch方法其實默認寫的就是這個handler。
深度監聽 deep屬性
watch 裏面還有一個屬性 deep,默認值是 false,代表是否深度監聽,如在本例中currentPerson初次賦值時能夠被handler監聽到,重新賦值時監聽不到,使用deep屬性能夠實現深度的監聽。
currentPerson: {
handler(val,oldVal){
console.log('監聽到了queryString的變化:',val.age,oldVal.age)
},
deep: true
},
props:用於接收來自父組件的數據
組件實例的作用域是孤立的。在子組件的模板內不能直接引用父組件的數據。父組件的數據需要通過 Prop 才能下發到子組件中,使用選項props申明該組件可接受的 prop 列表。
Prop可以理解爲在組件上註冊的一些自定義屬性,這些屬性的值可以通過組件的props選項接收到。
在本例中,在組件AgeStatistics中希望①獲得根組件的數據title②獲得靜態屬性bg-color,可以這樣傳遞屬性:
PS:html模板中屬性要使用短橫線分隔命名法(kebab-case)命名
<age-statistics v-bind:unit="title" bg-color="gray" inline-template>
...
<h1 :style="{backgroundColor: bgColor}">{{unit}}{{title}}</h1>
...
</age-statistics>
在組件實例的props選項中申明從父組件接受屬性unit、bgColor。
props:['unit','bgColor'],
單向數據流
:父級 prop 的更新會向下流動到子組件中,但是反過來則不行;每次父級組件發生更新時,子組件中所有的 prop 都將會刷新爲最新的值。