元件溝通的前提: 外層(父元件)與內層(子元件)資料狀態是分離的,預設無法相互傳遞,除非透過 props、emits、slot
一、定義/功能
- props 讓子元件可以使用父元件的 data
- 只能單向 父傳子
- 首先在子元件中聲明有什麼
props
- 父元件可以像使用 HTML attributes 一樣,使用子元件的
props
- 常會在父層 html 中跟
v-bind:
一起使用(傳遞動態值)
- emits (發射)讓子元件可以向父元件觸發事件
- 單向 子傳父
- emits 先在子元件中聲明有什麼
emits
- this.$emit
- slot (插槽)在子元件間開放給父元件的空間
- 形同父元件的飛地,可自由使用父元件的資料及方法
- 不能用子元件的東西,除非利用
slot props
- mitt 讓兩個同層子元件可以傳遞資料!(屬於外部套件)
- 兄弟傳兄弟(同個父層之下)
元件傳遞概念示意圖
二、關於 props
- props 怎麼寫?
- 陣列寫法
- 物件寫法
app.component
三、關於 emits
分頁換頁範例
- 父層:
@change_page="changePage"
<PaginationComponent :pagination="pagination" @change_page="changePage"></PaginationComponent
- 子層:
@click.prevent="$emit('change_page', i)"
<a href="#" class="page-link border-0 fs-sm" @click.prevent="$emit('change_page', i)">
四、關於 slot
slot
的目的是讓外層元件可以自由地定義子元件的部分內容,並透過Slot Props
將需要的資料傳遞到子元件中,讓子元件能夠根據傳遞的資料渲染對應的內容。這樣一來,外層元件就可以更加靈活地控制子元件的顯示方式,也能夠在多個地方重複使用同一個子元件,只需要透過插槽和Slot Props
將不同的資料傳遞進去即可。- slot props
▻案例練習 -props & slot props 應用
- 在這個範例中,我們先將外層元件的 group 資料透過 props 傳遞到子元件 Got7 中,接著在 Got7 元件的 template 中使用了 slot 元素來定義 header 和 main 這兩個插槽。在定義插槽時,我們使用了 v-bind 指令將 group.name 和 group.members 的值分別作為 title 和 members 的值傳遞到插槽中。
<div id="app"> <got7 :group="group"> <template #header="{ title }"> {{ title }} </template> <template #main=" { members } "> <ul> <li v-for="member in members" :key="member.id"> {{ member.name }} </li> </ul> </template> </got7> </div>
const got7 = {
props: {
group: {
type: Object,
required: true
}
},
template: `
<div class="container">
<div class="header h2 bg-light p-3">
// title(自定義名稱) 這裡使用 slot props
<slot name="header" :title="group.name">我是組合名</slot>
</div>
<div class="main mt-3 lh-lg">
// members(自定義名稱) 這裡使用 slot props
<slot name="main" :members="group.members">我是成員列表</slot>
</div>
</div>
`
};
const app = Vue.createApp({
// components 是個物件
components: {
got7
},
data() {
return {
group: {
name: "GOT7",
members: [
{ id: 1, name: "JayB" },
{ id: 2, name: "Mark" },
{ id: 3, name: "Jackson" },
{ id: 4, name: "Jinyoung" },
{ id: 5, name: "Youngjae" },
{ id: 6, name: "BamBam" },
{ id: 7, name: "Yugyeom" }
]
}
};
}
});
app.mount("#app");
參考文章
五、關於 mitt
- import
mitt
套件
<script type="module">
import 'https://unpkg.com/mitt/dist/mitt.umd.js'; // mitt
const emitter = mitt(); // emitter 為自訂變數名稱
</script>
- 傳出資料的子元件A使用
emitter.emit('自訂傳出函式變數名', 要帶入函式參數的值)
傳入資料的子元件B使用
emitter.on('自訂傳出函式變數名', (參數)=>{})
接收(監聽)- ⭐此處callback function內的參數可任意替換,但函式變數名接收跟傳入的要相同!