Vue.js slot插槽

1.我的理解的插槽

之因此使用組件,就是由於組件能夠將複雜的頁面分割成多個部分,每一個 部分就是一個組件(也是一個vue文件)。要使用這個組件,只須要引入組件文件,並在模版中寫入組件標籤便可,引入了這個子組件,就至關於引入了這個組件的html模版,例如:html

// App.vue
<template>
    <div id="app">
        <Child />
    </div>
</template>
// Child組件
<template>
    <div id="child">
        <h2>我是Child組件</h2>
    </div>
</template>

渲染以後就是vue

<div id="app">
   <div id="child">
      <h2>我是Child組件</h2>
   </div>
</div>

父組件想要插入數據到子組件中,無非就是將數據經過屬性綁定的形式,而後子組件經過props接收。可是這種方法只能用來傳遞一些純數據(字符串,對象和數組),沒法傳入一段html代碼給子組件,slot就是爲此而生的數組

2.slot基本用法

在原html中,咱們常常在一個塊級標籤中插入n個標籤,Vue中父組件給子組件插入標籤也是這種寫法app

// App.vue
<template>
  <div id="app">
    <Child>
      <!-- 在子組件中插入標籤 -->
      <h2>我是插入的h2</h2>
    </Child>
  </div>
</template>

父組件給子組件插入(傳遞)一段html標籤,子組件須要一個位置進行接收,這個位置就是子組件的slot標籤。slot標籤的位置就是插入標籤的位置code

// 子組件
<template>
    <div id="child">
<!-- slot標籤將被插入的標籤替代 -->
        <slot></slot>
        <h2>我是Hello組件</h2>
    </div>
</template>

渲染結果:htm

<div id="app">
    <div id="child">
        <h2>我是插入的h2</h2>
        <h2>我是Child組件</h2> 
    </div>
</div>

這種插槽只有一個,被稱爲匿名插槽。對象

3.具名插槽

若是子組件有多個插槽,就須要爲每一個插槽添加一個標識,即name屬性,方便對號入座ip

<template>
    <div id="child">
        <slot name="top"></slot>
        <h2>我是Child組件</h2>
        <slot name="bottom"></slot>
    </div>
</template>

父組件插入標籤時 經過設定slot屬性,對比slot的name屬性值,來關聯對應的插槽作用域

<template>
  <div id="app">
    <Child>
      <!-- 在子組件中插入標籤 -->
      <h2 slot="top">我是插入的h2</h2>
      <h5 slot="bottom">我是插入的h5</h5>
    </Child>
  </div>
</template>

渲染結果:字符串

<div id="app">
    <div id="child">
        <h2>我是插入的h2</h2>
        <h2>我是Child組件</h2> 
        <h5>我是插入的h5</h5>
    </div>
</div>

PS:插槽能夠空着不用,父組件不插入標籤元素,插槽就不會被渲染,利用這個特性能夠控制子組件的某些空間是否展現對應的元素
插槽和props傳參能夠同時使用,二者不衝突

4.插槽的默認內容

slot標籤內能夠寫html代碼,若是這個插槽沒有被替換,會顯示該插槽內的html內容,反之會被替換

<template>
    <div id="child">
        <slot name="top">
          <p>我是top插槽沒使用的時候展現的內容</p>
        </slot>
        <h2>我是Child組件</h2>
        <slot name="bottom"></slot>
    </div>
</template>
// App.vue
<template>
  <div id="app">
    <Child>
      <h5 slot="bottom">我是插入的h5</h5>
    </Child>
  </div>
</template>

渲染結果:

<div id="app">
    <div id="child">
        <p>我是top插槽沒使用的時候展現的內容</p> 
        <h2>我是Child組件</h2>
        <h5>我是插入的h5</h5>
    </div>
</div>

5.slot-scope(做用域插槽) 爲slot標籤綁定數據

這個功能相似反向props,子組件經過屬性綁定的形式,將相應的數據綁定到slot標籤中,當父組件要插入標籤來替換這個slot時,就能夠讀取這個綁定在slot標籤中的數據

// 子組件
<template>
    <div id="child">
 <!-- 在slot標籤中2個數據 -->
        <slot name="top" :p1="p1" :p2="p2">
        </slot>
        <h2>我是Hello組件</h2>
        <slot name="bottom"></slot>
    </div>
</template>

<script>
export default {
  data () {
    return {
      p1: {name: '喬治',age: 4},
      p2 :{name: '佩琪',age: 8}
    }
  }
}
</script>

父組件在替代slot的標籤中添加 slot-scope屬性,表示接受當前slot綁定的數據。slot-scope的值能夠隨意寫,例如slot-scope="xxx"
由於slot標籤上可能綁定了多個數據,因此vue將全部的數據都包裹在一個對象內,能夠經過這個對象的屬性名來訪問對應的數據。

// App.vue
<template>
  <div id="app">
    <Hello>
      <template slot-scope="xxx" slot="top">
        <p>{{xxx.p1.name}}</p>
        <p>{{xxx.p1.age}}歲</p>
        <p>{{xxx.p2.name}}</p>
        <p>{{xxx.p2.age}}歲</p>
      </template>
      <h5 slot="bottom">我是插入的h5</h5>
    </Hello>
  </div>
</template>

xxx.p1.name => 喬治 xxx.p1.age => 4 xxx.p2.name => 佩琪 xxx.p2.age => 8

相關文章
相關標籤/搜索