Day3 的文章有使用到資料傳遞,感覺開發上會蠻常用到的,今天就稍微深入了解一下兩個的區別
靜態傳入
最簡單的情境是父元件直接把一個靜態字串傳給子元件,子元件接收到 url,並顯示圖片。
const app = Vue.createApp({})
app.component('photo', {
props: ['url'],
template: `<img :src="url" class="img-thumbnail" alt>`
})
<photo url="https://example.com/demo.png"></photo>
動態傳入
大多時候我們要傳的會是父元件的資料,這時候就要用 v-bind,這樣當父元件的 imgUrl 改變時,子元件也會自動更新。
const app = Vue.createApp({
data() {
return {
imgUrl: 'https://example.com/dynamic.png',
}
},
})
app.component('photo', {
props: ['url'],
template: `<img :src="url" class="img-thumbnail" alt>`
})
<photo v-bind:url="imgUrl"></photo>
前面知道了 props 可以把資料從父元件傳給子元件,但其實 Vue 還提供了「型別檢查」和「驗證」的功能,讓元件更好維護。
內部型別驗證: 較常用於是否有預設值、是否為必填欄位
const app = Vue.createApp({
data(){
return {
money: 300,
big: 100n,
boo: truw,
fn: () => {return 'a'}
};
},
});
app.component('validation',{
props: {
propA: Function,
propB: [String, Number],
//是否為必填
propC: {
type: String,
required: true,
},
//是否有預設值
propD: {
type: Number,
default: 10,
},
}
});
<validation
:prop-a="fn"
prop-c="123"
> <!--prop-c 為判斷有沒有填資料,若有資料則不會報錯,若沒有資料則會報錯-->
</validation>
在 Vue 裡,資料是由外往內傳(props),但如果子元件需要把「使用者操作」回報給父元件,就要用 emit。
可以把它想像成:子元件丟一個事件給父元件,父元件再決定要怎麼處理。
<button-counter v-on:emit-num="addNum"></button-counter>
<button-text @emit-text="getData"></button-text>
<button-named></button-named>
const app = Vue.createApp({
data() {
return {
num: 0,
text: '',
};
},
methods: {
addNum(){
this.num++;
}
getData(text){
this.text = text;
}
}
});
app.component('button-counter',{
methods:{
click(){
this.$emit('emit-num')
}
},
template: `<button type="button" @click="click">add</button>`
)};
//將內層文字往外傳
app.component('button-text',{
data() {
return {
text: '內部',
}
},
methods:{
emit(){
this.$emit('emit-text', this.text)
}
},
template: `<button type="button" @click="emit">emit data</button>`
)};
不只可以在 props 上做型別驗證,連 emit 出去的事件也能做檢查,這樣能避免子元件亂丟錯誤資料。
app.component('button-counter2',{
emits: {
add:(num) => {
return typeof num === "number"; //會回傳 true 或 false
}
},
template: `<button type="button" @click="$emit('add',num)">add</button>`
)};
小結
- Props 將資料由外向內傳入
- Emit 將事件由內向外傳