[Vue3] 元件溝通術 props、emits、slot 、mitt怎麼用


元件溝通的前提: 外層(父元件)與內層(子元件)資料狀態是分離的,預設無法相互傳遞,除非透過 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 應用

GOT7練習範例

  • 在這個範例中,我們先將外層元件的 group 資料透過 props 傳遞到子元件 Got7 中,接著在 Got7 元件的 template 中使用了 slot 元素來定義 header 和 main 這兩個插槽。在定義插槽時,我們使用了 v-bind 指令將 group.name 和 group.members 的值分別作為 title 和 members 的值傳遞到插槽中。
    GOT7元件傳遞示意圖
    <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內的參數可任意替換,但函式變數名接收跟傳入的要相同!
  • https://www.casper.tw/development/2020/12/15/vue-3-mitt/

#vue3 #Vue #Props #emit







你可能感興趣的文章

Laravel 5 component & slot

Laravel 5 component & slot

Servlet接收前端Ajax傳遞的Json資料

Servlet接收前端Ajax傳遞的Json資料

財務分析(3) --  抓取公開資訊觀測站財務指標

財務分析(3) -- 抓取公開資訊觀測站財務指標






留言討論