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

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

1、插槽

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

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

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

<button>提交</button>

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

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

2、具名插槽

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

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指令,並讓插槽名稱成爲它的參數,以下所示。ip

<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>元素),都會傳遞給沒有名稱的插槽(即默認插槽)。io

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

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

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

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

3、做用域插槽

  在講解做用域插槽以前,須要要先了解一下編譯做用域。

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>
相關文章
相關標籤/搜索