iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 28
0
Modern Web

小白的JavaScript讀書日記系列 第 28

Day28:Vue.js(十)

動態設定樣板內容(slot)

  • slot是一種用於內容分配的元件,想像是在內容中開好洞,在等東西放進去
  • 有分具名以及不具名
  • slot可以包含任何模板的內容,包含HTML。
  • 將外層的元件放入子層的元件的指定位置中。
<body>
  <div id="app">
    <alert-box>
      我湖總冠軍?
    </alert-box>
  </div>
  <script>
    Vue.component('alert-box', {
      template: `<div>
      <slot></slot>
     <strong>還有我大金塊還沒打贏呢!</strong>
     </div>`
    })
    new Vue({
      el: '#app'
    })
  </script>
</body>

範例中可以看到<slot></slot>這段代表了在HTML裡面寫的<alert-box></alert-box>這樣很像看不出個所以然...我們稍微修改一下:

<body>
  <div id="app">
    <alert-box>
    </alert-box>
  </div>
  <script>
    Vue.component('alert-box', {
      template: `<div>
      <slot>想得美!</slot>
     <strong>還有我大金塊還沒打贏呢!</strong>
     </div>`
    })
    new Vue({
      el: '#app'
    })
  </script>
</body>

當我們在<alert-box>沒輸入內容時,在<slot>的內容就會顯示。

具名的slot

當我們同時需要很多個slot,就可以在slot內命名,<slot name="xx">以便區分。

<body>
  <div id="app">
    <alert-box>
      <h2 slot="header">NBA今年總冠軍是誰</h2>
      <p slot="footer">我大金塊?</p>
      <p>我大湖人?</p>
    </alert-box>
  </div>
  <script>
    Vue.component('alert-box', {
      template: `<div>
      <header>
      <slot name="header"></slot>
      </header>
      <main><slot></slot>
      </main>
      <footer><slot name="footer"></slot>
      </footer>
     </div>`
    })
    new Vue({
      el: '#app'
    })
  </script>
</body>

我們這邊預期在網頁上看到的畫面應該要是:
https://ithelp.ithome.com.tw/upload/images/20200925/20129488LffdfuFsaw.png

但實際看到的畫面如下:
https://ithelp.ithome.com.tw/upload/images/20200925/20129488QhqP2fMD5V.png
這是因為我們在模板中先寫好了對應的slot,而沒有具名的slot則會對應到沒有名字的。
因此可以觀察到:
<slot name="header">對應到<h2 slot="header">
<slot name="footer">對應到<p slot="footer">
沒具名的<slot>對應到<p>
但在模板中排的順序是:

  <header><slot name="header"></slot></header> //NBA今年總冠軍是誰
  <main><slot></slot></main>  //我大湖人?
   <footer><slot name="footer"></slot></footer> //我大金塊?

因此會得到上圖畫面中的結果。

也有v-slottemplate標籤搭配可以達到slot的效果:

    <alert-box>
      <template #footer>
        我大金塊?
      </template>
      <template v-slot:header>
        NBA今年總冠軍?
      </template>
      <p>我大湖人</p>
    </alert-box>

我們用v-slot搭配template標籤調整<alert-box>的內容,就算亂排後也可以達到和前一個例子一樣的結果p.s.:v-slot:xxx可以縮寫成#xxx

scoped-slot 特性

scoped-slot特性是為了讓子元件中的資料能在父層元件的的插槽(slot)中可以使用:

<body>
  <div id="app">
    <current-user v-slot="slotProps">
      Welcome:{{slotProps.user.firstName}}
    </current-user>
  </div>
  <script>
    Vue.component('current-user', {
      data: () => ({
        data_user: { firstName: 'Ben', lastName: 'Tsai' },
      }),
      template: `<span>
        <slot :user="data_user">
        Welcome:{{data_user.firstName}}
        </slot>       
      </span>`
    })
    new Vue({
      el: '#app'
    })
  </script>
</body>

上述例子中我們先將子元件內的data中的data_user物件綁定為slot元素的屬性:
<slot v-bind:user="data_user">
綁定在<slot>上的屬性被稱為slot props。
我們在父層可以用帶值的v-slot來定義slot props的名字(範例中:v-slot="soltProps""soltProps"可以任意命名),
我們在用這個命名的slot props來讀取子元件內data_user的資料。


今日總結

slot的使用以及特性
我自己是感覺比較複雜...短短內容研究了好久也還不太清楚ㄉ樣子
這邊也附上官方文件以供參考囉~


上一篇
Day27:Vue.js(九)
下一篇
Day29:Vue.js(十一)
系列文
小白的JavaScript讀書日記30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言