文章同時刊載於Andy's Blog
延續昨天話題,今天會來繼續聊聊props使用注意細節。
我們今天如果使用AJAX讀取遠端資料時,並透過props將資料傳入子元件時,有可能在畫面上無法正常顯示(如下圖)。而這個原因就是AJAX非同步特性,造成遠端回傳資料尚未載入,而使畫面一片空白。
這時,我們該如何解決呢?
我們可以透過簡單v-if來判斷,當資料完全載入時,在呈現於畫面上就可以瞜。
<div id="app">
<div class="row">
<div class="col-sm-4">
<!-- 這邊主要因為AJAX時間差,造成卡片載入錯誤。我們只要使用v-if成功載入時再渲染就不會跳錯 -->
<card :user-data="user" v-if="user.gender"></card>
</div>
</div>
</div>
說明:一個非prop 特性是指傳向一個組件,但是該組件並沒有相對應prop定義的特性。
我自己的理解如下(如果有錯,再請大家糾正):
如下範例:假設今天我們在元件上要放置一張圖片,而我們在template中並沒撰寫圖片的height
、width
、alt
屬性,這時Vue允許我們可以直接將這些特性撰寫在HTML上,如此一來這些特性就會被放置在元件實體內。(感覺有點像data-* ,自定義屬性方法)
例子如下:練習連結
HTML部分
<div id="app">
<h2>Default</h2>
<nicolas-cage alt="hello"></nicolas-cage>
<p>
<h2>H/W</h2>
<nicolas-cage width="199" height="199"></nicolas-cage>
</div>
JavaScript
Vue.component('nicolas-cage', {
template:'<img :src="url" />', //取得computed中url結果
data() {
return {
}
},
computed:{
url:function() {
let theUrl = 'https://fakeimg.pl/'+this.width+'/'+this.height;
return theUrl;
}
},
props:{
height:{
default:400,
},
width:{
default:400
}
}
});
var app = new Vue({
el: '#app',
data() {
return {
}
}
});
說明:可以注意到元件的template中並沒有用mustache語法
來綁定外部傳進來資料。
我們上面提到,如果在元件template上
並沒有相對應props屬性,但我們卻在HTML template上直接撰寫attribute,Vue會讓這些attribute直接寫入元件實體中。
範例<bootstrap-date-input>
的模板內容
<input type="date" class="form-control">
HTML上模板
<bootstrap-date-input
data-date-picker="activated"
class="date-picker-theme-dark"
></bootstrap-date-input>
最終顯示結果
form-control,這是在組件的模板內設置好的
date-picker-theme-dark,這是從組件的父級傳入的
剛有提到,因為非Prop的特性,即使我們在元件中並沒有使用props來定義型態或接受資料,Vue仍然會把在HTML上撰寫的特性放置於元件實體中。而今天如果我們不想要繼承元件內實體屬性,我們可以這樣做~
範例如下:
Vue.component('my-component', {
inheritAttrs: false,
// ...
})
而我們也因為可以設定inheritAttrs: false
和$attrs
緣故,可以自行決定哪些attribute要放置到哪個元素中。像是下方範例,我們透過v-bind="$attrs"
,將元件內實體屬性放置在input
中。
範例如下:
Vue.component('base-input', {
inheritAttrs: false,
props: ['label', 'value'],
template: `
<label>
{{ label }}
<input
v-bind="$attrs"
v-bind:value="value"
v-on:input="$emit('input', $event.target.value)"
>
</label>
`
})
在撰寫非Prop的特性(Non-Prop Attributes)
時,因為我是第一次接觸這個特性,撰寫起來有點卡卡的,也不太確定是否理解正確(哈哈)。我其實對於實務上會用在哪些地方,其實我也蠻好奇的,若有前輩願意分享也歡迎下方留言,那我們就明天見啦~