Vue躬行記(6)——內容分發


  Vue提供了一種內容分發技術,可將父組件中的內容傳遞給子組件的模板,實現方式參照了Web組件規范草案。

一、插槽

  Vue內置了一個<slot>元素,能作為插槽(slot)存在,而插槽內可包含文本、HTML片段、組件等。以下面的btn組件為例,其模板中包含一個<slot>元素,在DOM中為btn組件添加了文本內容。

<btn>提交</btn>
<script>
  Vue.component("btn", {
    template: '<button><slot></slot></button>'
  });
</script>

  渲染出的<button>元素會包含“提交”,即插槽被替換成了分發的內容,如下所示。

<button>提交</button>

  在插槽中允許添加默認的內容(即為<slot>元素附加內容,如下所示),當父組件沒有傳遞內容時,它們就會被渲染。

Vue.component("btn", {
  template: '<button><slot>提交</slot></button>'
});

二、具名插槽

  具名插槽是指包含名稱的插槽,即指定了name特性的<slot>元素。當組件的模板中需要多個插槽時,就得通過名稱來加以區分。例如有一個page組件,包含三個<slot>元素,其中有兩個聲明了name特性,如下所示。

Vue.component("page", {
  template: `<div>
        <header><slot name="header"></slot></header>
        <section><slot></slot></section>
        <footer><slot name="footer"></slot></footer>
    </div>`
});

  如果要向具名插槽傳遞內容,那么可以在<template>元素上使用v-slot指令,並讓插槽名稱成為它的參數,如下所示。

<page>
  <template v-slot:header>
    <h1>頭部</h1>
  </template>
  <p>內容</p>
  <template v-slot:footer>
    <h1>尾部</h1>
  </template>
</page>

  渲染出的DOM結構如下所示,分發的內容替換了對應的插槽。

<div>
  <header>
    <h1>頭部</h1>
  </header>
  <section>
    <p>內容</p>
  </section>
  <footer>
    <h1>尾部</h1>
  </footer>
</div>

  所有沒有被包裹在帶v-slot指令的<template>元素中的內容(例如上面的<p>元素),都會傳遞給沒有名稱的插槽(即默認插槽)。

  注意,一個不帶name特性的<slot>元素,其實也有名稱,叫default。在v-slot指令中,也可以對其進行指定,如下所示。

<template v-slot:default>
  <p>內容</p>
</template>

  v-slot指令不僅支持動態參數,還允許特殊的縮寫,即將參數前的v-slot:替換成#號,如下所示。

<template v-slot:[obj.header]></template>
<template #header></template>

三、作用域插槽

  在講解作用域插槽之前,需要要先了解一下編譯作用域。

1)編譯作用域

  父組件模板中的內容都是在父級作用域中編譯的,而子組件模板中的內容都是在子級作用域中編譯的,即兩級作用域中的數據無法相互訪問。下面以btn組件為例,它的模板中包含一個插槽,並在數據對象中聲明了一個txt屬性。

Vue.component("btn", {
  data: function() {
    return { txt:"提交" };
  },
  template: '<button><slot></slot></button>'
});

  在為btn組件提供插值形式的內容時,如下代碼所示,由於當前作用域不存在txt屬性,因此會拋出錯誤。

<btn>{{txt}}</btn>

2)作用域插槽

  這是一種特殊的插槽,其內容可訪問子組件中的數據,即把模板傳給插槽而不是渲染好的內容。還是以btn組件為例,與之前不同的是,為<slot>元素自定義了一個txt特性,並為其綁定數據對象的txt屬性,如下所示。

Vue.component("btn", {
  data: function() {
    return { txt:"提交" };
  },
  template: '<button><slot :txt="txt"></slot></button>'
});

  在使用btn組件時,需要為v-slot指令傳遞一個變量,名稱可自定義(例如slots),其值是由插槽上的自定義特性所組成的對象。

<btn>
  <template v-slot:default="slots">
    {{slots.txt}}
  </template>
</btn>

  當只提供了默認插槽時,可將v-slot指令轉移到組件上,並且可省略default名稱,如下所示。

<btn v-slot="slots">
  {{slots.txt}}
</btn>

  注意,縮寫形式的默認插槽不能與具名插槽混用,因為這樣會導致作用域不明確。

<btn v-slot="slots">
  {{slots.txt}}
  <template v-slot:custom></template>
</btn>

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM