回首Vue3之指令篇(八)

這是我參與8月更文挑戰的第8天,活動詳情查看:8月更文挑戰html

這篇文章咱們來說一下v-slot的使用方法,以及在使用它的時候咱們須要注意的地方。vue

如何使用

v-slot結合<slot>元素提供具名插槽或須要接收 prop 的插槽。v-slot的簡寫爲#,只可用於<template>組件中。編程

基礎使用

假定咱們自定義一個組件my-button爲:markdown

<button>   
    <slot>提交</slot> 
</button>
複製代碼

slot元素中,咱們能夠給默認值(使用組件不傳內容的時候會顯示默認值,不然默認值會被替換),也能夠爲空,直接爲<slot></slot>。那麼咱們該怎麼去使用這個組件呢,以下:app

<my-button>
    1. 此處什麼都不放,編譯後顯示默認值
    
    2. 此處能夠放字符串
    
    3.此處能夠聽任何模板代碼 或 組件
</my-button>
複製代碼

此外,須要咱們注意的是:父級模板裏的全部內容都是在父級做用域中編譯的;子模板裏的全部內容都是在子做用域中編譯的。也就是說<my-button></my-button>包裹的內容不能訪問my-button的做用域。dom

具名插槽

有時咱們須要多個插槽,<slot> 元素有一個特殊的 attribute:name,咱們可使用這個屬性來寫你須要的插槽,假定一個組件base-layout以下:ide

<div class="container">
  <header>
    <slot name="header"></slot>
  </header>
  <main>
    <slot></slot>
  </main>
  <footer>
    <slot name="footer"></slot>
  </footer>
</div>
複製代碼

屬性name不存在的時候,<slot> 出口會帶有隱含的名字「default」。那麼咱們該怎麼使用呢,以下:函數

<base-layout>
    //使用 v-slot
  <template v-slot:header>
    <h1>name爲header的插槽</h1>
  </template>

    //默認插槽能夠不用寫 v-slot:default ,可是若是用縮寫的方式就須要寫上 #default
  <template #default>
    <p>v-slot 時能夠不用寫</p>
    <p>縮寫時要加上 #default</p>
  </template>
    
    //使用縮寫 #
  <template #footer>
    <p>縮寫形式</p>
  </template>
</base-layout>
複製代碼

做用域插槽

爲了讓插槽內容可以訪問子組件中才有的數據,咱們可使用做用於插槽。oop

用法

單個插槽 假定組件todo-list爲:post

<ul>
  <li v-for="(item, index) in items">
    <slot :item="item" :index="index"></slot>
  </li>
</ul>
複製代碼

使用時咱們能夠有兩種方式:

  1. v-slot做用在組件上
<todo-list v-slot="slotProps">
    //slotProps 是個對象,包含了綁定在 slot 上除 name 之外的全部屬性,例如上述包含了item、index
    //slotProps 是個變量,能夠取任意名字
    
    //此時不能用template包裹
    <span>{{slotProps.item}}</span>
</todo-list>
複製代碼

咱們這個例子是默認插槽,若是例子中是具名插槽,好比 slotname="header",那咱們要這樣使用:

<todo-list v-slot:header="slotProps">
    <span>{{slotProps.item}}</span>
</todo-list>
複製代碼
  1. v-slot做用在插槽包裹元素template
<todo-list>
    //必定要用 template 包裹,由於v-slot只能用於 template 或 組件中
    <template v-slot="slotProps">
        <span>{{slotProps.item}}</span>
    </template>
</todo-list>
複製代碼

若是組件給了一個具名插槽,使用方法和1相同。

多個插槽

此時v-slot只能做用在插槽包裹元素template上,假定組件todo-list爲:

<ul>
  <li v-for="(item, index) in items">
    <slot name="slot1" :item="item" :index="index"></slot>
    <slot name="slot2" :item="item" :index="index"></slot>
    <slot name="slot3" :item="item" :index="index"></slot>
  </li>
</ul>
複製代碼

使用方法以下:

<todo-list>
    //slot1
    <template v-slot:slot1="slotProps">
        <span>{{slotProps.item}}</span>
    </template>
    
    //slot2
    <template v-slot:slot2="slotProps">
        <span>{{slotProps.item}}</span>
    </template>
    
    //slot3
    <template v-slot:slot3="slotProps">
        <span>{{slotProps.item}}</span>
    </template>
</todo-list>
複製代碼

解構插槽Prop

經過上述內容咱們知道slotProps是個對象,那麼咱們在使用的時候能夠解構插槽。咱們以1的具名插槽爲例:

<todo-list v-slot:header="{item,index}">
    <span>{{item}} {{index}}</span>
</todo-list>

或者

<todo-list v-slot:header="{item:x,index:y}">
    <span>{{x}} {{y}}</span>
</todo-list>
複製代碼

動態插槽

動態指令參數也能夠用在 v-slot 上,來定義動態的插槽名,也就是說你能夠根據本身的需求,來動態的改變插槽內容,以下:

<base-layout>
  <template v-slot:[dynamicSlotName]>
    ...
  </template>
</base-layout>
複製代碼

假設你有三個插槽,可是你每次只想展現一個插槽內容,那麼咱們就能夠用動態插槽來作這件事。

注意事項

Vue3統一了普通插槽和做用域插槽。當使用渲染函數時,即 h,將插槽定義爲當前節點的子對象,以下:

h(LayoutComponent, {}, {
  header: () => h('div', this.header),
  content: () => h('div', this.content)
})
複製代碼

當你須要以編程方式引用做用域插槽時,Vue3與Vue2的用法是不同的,在Vue3中它們如今被統一到 $slots 選項中,使用以下:

// 2.x 語法
this.$scopedSlots.header

// 3.x 語法
this.$slots.header()
複製代碼

總結

  1. 使用動態插槽可讓咱們在處理同一區域複雜內容切換更靈活。

  2. Vue3<template>裏面能夠放代碼片斷,因此咱們能夠在使用插槽的時候,裏面能夠放不少的dom或組件。

  3. 具名插槽和解構插槽Prop均可以讓我更好的去完成需求,咱們能夠根據本身的狀況,去合理的使用它們。

相關文章
相關標籤/搜索