[Vue] 元件-Props
TL;DR
參考資料
相關連結
定義Props
因為每個元件內各自的資料是獨立的。
如果今天父元件內需要掛載一個子元件,而子元件想要取用到父元件的資料時,我們需要在子元件定義一個Props
的屬性。
- html(#app)
- vue
<div id="app">
<div class="p-5">
<h3>Props 靜態資料</h3>
<photo url="https://images.unsplash.com/photo-1605784401368-5af1d9d6c4dc?ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=600&q=80"></photo>
<h3>動態資源</h3>
<photo :url="imgUrl"></photo>
</div>
</div>
const app = Vue.createApp({
data() {
return {
imgUrl: 'https://images.unsplash.com/photo-1605784401368-5af1d9d6c4dc?ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=600&q=80',
};
},
});
app.component('photo', {
props:['url'],
template: `<img :src="url" class="img-thumbnail" alt>`
});
app.mount('#app');
props口訣
在 Line:7 中,同時會撰props
內所定義的變數名稱,以及父元件內的資料變數名稱。
口訣為:前內後外
寫在前面的為內層子元件所定義的props
,後面為外層父元件的變數名稱。
Props的單向數據流
外層所傳入的資料,子元件是無法去修改值的。
- html(#app)
- vue
<div id="app">
<div class="p-5">
{{`外層imgUrl的值:${imgUrl}`}}
<photo :url="imgUrl"></photo>
</div>
</div>
const app = Vue.createApp({
data() {
return {
imgUrl: 'https://images.unsplash.com/photo-1605784401368-5af1d9d6c4dc?ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=600&q=80',
};
},
});
app.component('photo', {
props:['url'],
template:`
<img :src="url" class="img-thumbnail" alt>
<input type="text" class="form-control" v-model="url">
{{url}}
`
});
app.mount('#app');
例外
單向數據流只限定第一層 因為陣列以及物件在傳遞的時候是使用傳址(call by reference)的方式去傳遞的。
所以雖然我們無法變更參考的記憶體位置,但是內層的資料我們可以更動,並且也會反映在父層元素上的資料中。
- html(#app)
- vue
<div id="app">
<div class="p-5">
<!-- 修改photoarray元件內透過v-model所綁定的資料,仍然會改動到外層父元件內imgUrls陣列內資料的值 -->
{{`外層imgUrl的值:${imgUrls}`}}
<photoarray :url="imgUrls"></photoarray>
</div>
</div>
const app = Vue.createApp({
data() {
return {
imgUrls:['https://images.unsplash.com/photo-1697369964069-b4730db68547?crop=entropy&cs=srgb&fm=jpg&ixid=M3wzMjM4NDZ8MHwxfHJhbmRvbXx8fHx8fHx8fDE3MDEwNzk2MTl8&ixlib=rb-4.0.3&q=85',
'https://images.unsplash.com/photo-1698725224267-472f2f3cf858?crop=entropy&cs=srgb&fm=jpg&ixid=M3wzMjM4NDZ8MHwxfHJhbmRvbXx8fHx8fHx8fDE3MDEwNzk2MTl8&ixlib=rb-4.0.3&q=85']
};
},
});
app.component('photoarray', {
props:['url'],
template:`
<img :src="url[1]" class="img-thumbnail" alt>
<input type="text" class="form-control" v-model.lazy="url[1]">
{{url[1]}}
`
});
app.mount('#app');
型別驗證
如果要在傳入資料時進行型別的驗證,需要將剛剛子元件中所定義的props陣列
改為props物件
。
預備知識
如果不使用動態屬性v-bind,則一律傳入的值都是字串型別。
使用v-bind時,“”
內的值會如同表達式,可以填入任何變數或是物件實字等等不同型別。
- html(#app)
- vue
<div id="app">
<div class="p-5">
<!-- 直接使用money屬性則傳入的值300會顯示為字串 (傳入true也會顯示字串true) -->
<props-type money="300"></props-type>
<!-- 使用v-bind綁定時,則傳入值型別會相同 -->
<props-type :money="money"></props-type>
</div>
</div>
const app = Vue.createApp({
data() {
return {
money: 300
};
}
});
app.component("props-type", {
props: ["money"],
template: `<div>value: {{money}}, typeof:{{ typeof money }}</div>`
});
app.mount("#app");
型別驗證不影響運作
就算型別驗證沒有通過,仍然可以正常執行js
只是會在開發者工具上看到Vue warning
codepen受限於環境故看不到 Vue warning