iT邦幫忙

第 11 屆 iT 邦幫忙鐵人賽

DAY 11
1
自我挑戰組

新手初探 Vue系列 第 19

鐵人賽Day20 - slot 插槽

前面幾篇講到了元件,並介紹元件之間由外而內資料傳遞的屬性 props 還有由內而外傳遞的事件 emit
元件也不只可以重複的讓我們來做使用,如果今天一個元件我們只想要替換部分內容也是可行的
這時候就要來介紹 slot 了,也就是替換部分內容
首先先照前面的方式建立一個元件:

<div id="app">
  <h2>沒有插槽可替換的狀態</h2>
  <no-slot-component></no-slot-component>
</div>

<script type="text/x-template" id="noSlotComponent">
<div class="alert alert-warning">
  <h6>我是一個元件</h6>
  <p>
    這沒有插槽。
  </p>
</div>
</script>

<script>
Vue.component('no-slot-component', {
  template: '#noSlotComponent',
});

var app = new Vue({
  el: '#app',
  data: {}
});
</script>

這時候如果在 no-slot-component 元件內,加上一些內容:

<div id="app">
  <h2>沒有插槽可替換的狀態</h2>
  <no-slot-component>
      <p>這是一段置換的內容</p>
  </no-slot-component>
</div>

會發現內容根本沒有被呈現出來

如果今天換成另外一種情況:

<div id="app">
  <h2>Slot 基礎範例</h2>
  <single-slot-component>
    <p>使用這段取代原本的 Slot。</p>
  </single-slot-component>
</div>

<script type="text/x-template" id="singleSlotComponent">
<div class="alert alert-warning">
  <h6>我是一個元件</h6>
  <div>
    如果沒有內容,則會顯示此段落。
  </div>
</div>
</script>

<script>
Vue.component('single-slot-component', {
  template: '#singleSlotComponent',
})

var app = new Vue({
  el: '#app',
  data: {}
});
</script>

我們在 single-slot-component 元件內新增了一個 <p>,然後在 x-template 的地方新增一個 <slot> 標籤:

<script type="text/x-template" id="singleSlotComponent">
<div class="alert alert-warning">
  <h6>我是一個元件</h6>
  <div>
    如果沒有內容,則會顯示此段落。
  </div>
  <slot></slot>
</div>
</script>

會發現內容就被呈現出來了,有趣的是當我們替換成下面的樣子時:

<script type="text/x-template" id="singleSlotComponent">
<div class="alert alert-warning">
  <h6>我是一個元件</h6>
  <slot>
    如果沒有內容,則會顯示此段落。
  </slot>
</div>
</script>

如果 single-slot-component 元件沒有任何內容時,就會顯示 <slot> 標籤內的內容,如果有的話,就是呈現插入的內容

如果我們想要多個部分內容置換時:

<div id="app">
  <h2>具名插槽</h2>
  <named-slot-component>
    <header>替換的 Header</header>
    <template>替換的 Footer</template>
    <template>按鈕內容</template>
  </named-slot-component>
</div>

<script type="text/x-template" id="namedSlotComponent">
<div class="card my-3">
  <div class="card-header">
    <div>這段是預設的文字</div>
  </div>
  <div class="card-body">
    <slot>
      <h5 class="card-title">Special title treatment</h5>
      <p class="card-text">With supporting text below as a natural lead-in to additional content.</p>
    </slot>
    <a href="#" class="btn btn-primary">
      <div>spanGo somewhere<div>
    </a>
  </div>
  <div class="card-footer">
    <div>這是預設的 Footer</div>
  </div>
</div>
</script>

<script>
Vue.component('named-slot-component', {
  template: '#namedSlotComponent',
});

var app = new Vue({
  el: '#app',
  data: {}
});
</script>

我們已經把要置換的內容放在 named-slot-component 元件裡面了,這時候我們只要在 x-template 的地方,把要置換的部分對應起來,這時候除了用 slot 標籤之外,還要賦予 name 這個屬性,值可以自定義,如下:

<script type="text/x-template" id="namedSlotComponent">
<div class="card my-3">
  <div class="card-header">
    <slot name="header">這段是預設的文字</slot>
  </div>
  <div class="card-body">
    <slot>
      <h5 class="card-title">Special title treatment</h5>
      <p class="card-text">With supporting text below as a natural lead-in to additional content.</p>
    </slot>
    <a href="#" class="btn btn-primary">
      <div>spanGo somewhere<div>
    </a>
  </div>
  <div class="card-footer">
    <div>這是預設的 Footer</div>
  </div>
</div>
</script>

然後在 named-slot-component 元件置換內容的部分,新增 slot 屬性,值就是我們剛剛自定義 name 屬性的值

<div id="app">
  <h2>具名插槽</h2>
  <named-slot-component>
    <header slot="header">替換的 Header</header>
    <template>替換的 Footer</template>
    <template>按鈕內容</template>
  </named-slot-component>
</div>

這時候內容就會替換上去了,其他地方也是一樣的,但是有發現我元件內的置換內容有用到 <template> 標籤,這是不會被輸出的,所以置換時並不會去動到原有的 HTML 結構,可以打開開發人員工具就知道了


上一篇
鐵人賽Day19 - 向外傳遞事件 emit
下一篇
鐵人賽Day21 - ES6 之 let 和 const
系列文
新手初探 Vue30

尚未有邦友留言

立即登入留言