如何使用Vue中的嵌套插槽(包括做用域插槽)

做者:Michael Thiessen
譯者:前端小智
來源:medium
點贊再看,養成習慣

本文 GitHub https://github.com/qq44924588... 上已經收錄,更多往期高贊文章的分類,也整理了不少個人文檔,和教程資料。歡迎Star和完善,你們面試能夠參照考點複習,但願咱們一塊兒有點東西。前端

最近我弄清楚瞭如何遞歸地實現嵌套插槽,包括如何使用做用域插槽來實現。原由是我想看看是否能夠構建一個複製v-for指令但僅使用template組件。vue

它還支持插槽和做用域插槽,也能夠支持命名插槽,咱們能夠這樣使用它:git

<template>
  <div>
    <!-- Regular list -->
    <v-for :list="list" />
    
    <!-- List with bolded items -->
    <v-for :list="list">
      <template v-slot="{ item }">
        <strong>{{ item }}</strong>
      </template>
    </v-for>
  </div>
</template>

第一個將正常打印列表,而第二個將每一個項包裝在<strong>標記中。github

這不是一個很是有用的組件,但能夠從中學到的最多,咱們來看看。面試

無循環實現循環

一般,當咱們要渲染元素或組件的列表時,可使用v-for指令,但此次咱們但願徹底擺脫它。編程

那麼,咱們如何在不使用循環的狀況下渲染項目列表呢?就是使用 遞歸數組

咱們可使用遞歸來渲染項目列表。過程並不會複雜,咱們來看看怎麼作。微信

遞歸表示一個列表

我在大學裏最喜歡的課程之一是「編程語言概念」編程語言

對我來講,最有趣的部分是探索函數式編程和邏輯編程,並瞭解與命令式編程的區別(Javascript 和最流行的語言是命令式編程)。函數式編程

這門課讓我真正瞭解如何使用遞歸,由於在純函數語言中,一切都是遞歸。無論怎樣,從那門課我學到了可使用遞歸地表示一個列表。

與使用數組不一樣,每一個列表是一個值(頭)和另外一個列表(尾)。

[head, tail]

例如要表示列表[一、二、3],則能夠遞歸方式表示爲:

[1, [2, [3, null]]]

咱們必須以某種方式結束列表,所以咱們使用null而不是另外一個數組(也可使用空數組)。

看到這裏,你或許就能夠明白了,咱們可使用此概念並將其應用於咱們的組件。 相反,咱們將遞歸嵌套組件以表示列表。

咱們最終將渲染出這樣的內容。 注意咱們「list」的嵌套結構:

<div>
  1
  <div>
    2
    <div>
      3
    </div>
  </div>
</div>

誠然,這與v-for渲染的效果並不徹底相同,但這也不是本練習的重點。

構建組件

首先,咱們將解決遞歸渲染項目列表的問題。

使用遞歸來渲染列表

此次咱們使用一個普通數組,而不是使用前面介紹的遞歸列表:

[1, 2, 3]

這裏要討論兩種狀況:

  • 基本情形-渲染列表中的第一項
  • 遞歸情形-渲染項目,而後沉浸下一個列表

咱們把[1,2,3]傳給v-for

<template>
  <v-for :list="[1, 2, 3]" />
</template>

咱們但願獲取列表中的第一項,即1,並顯示它

<template>
  <div>
    {{ list[0] }}
  </div>
</template>

如今,該組件將渲染1,就像咱們指望的那樣。

可是咱們不能只渲染第一個值並中止。 咱們須要渲染值,而後還渲染列表的其他部分:

<template>
  <div>
    {{ list[0] }}
    <v-for :list="list.slice(1)" />
  </div>
</template>

咱們不傳遞整個list數組,而是刪除第一項並傳遞新數組。第一個項目咱們已經打印出來了,因此沒有必要保留它。

順序是這樣的:

  1. 咱們將[1,2,3]傳遞到v-for中進行渲染
  2. 咱們的v-for組件渲染1,而後將[2,3]傳遞到下一個v-for進行渲染
  3. [2,3]並渲染2,而後將[3]傳遞到下一個v-for
  4. 最後一個v-for組件渲染出3,咱們已經打印出列表!

如今,咱們的Vue應用程序的結構以下所示:

<App>
  <v-for>
    <v-for>
      <v-for />
    </v-for>
  </v-for>
</App>

能夠看到,咱們有幾個v-for組件,它們彼此嵌套在一塊兒。最後一件事,咱們須要中止遞歸

<template>
  <div>
    {{ list[0] }}
    <v-for
      v-if="list.length > 1"
      :list="list.slice(1)"
    />
  </div>
</template>

最終,渲染完全部項後,咱們須要中止遞歸操做。

遞歸嵌套的插槽

如今,組件能夠正常工做,可是咱們也但願它與做用域內插槽一塊兒使用,由於這樣能夠自定義渲染每一個項的方式:

<template>
  <v-for :list="list">
    <template v-slot="{ item }">
      <strong>{{ item }}</strong>
    </template>
  </v-for>
</template>

嵌套插槽

一旦弄清楚瞭如何遞歸地嵌套插槽,就會對它癡迷同樣的感嘆:

  • 嵌套n級的插槽
  • 遞歸插槽
  • 包裝組件將一個插槽轉換爲多個插槽

首先,咱們將簡要介紹嵌套插槽的工做方式,而後介紹如何將它們合併到v-for組件中。

假設咱們有三個組件:ParentChildGrandchild。咱們但願傳遞來自Parent組件的一些內容,並在Grandchild組件中渲染它。

Parent開始,咱們傳遞一些內容:

// Parent.vue
<template>
  <Child>
    <span>Never gonna give you up</span>
  </Child>
</template>

咱們在Child組件中作一些事情,將在稍後介紹。 而後咱們的Grandchild組件獲取插槽並渲染內容:

// Grandchild.vue
<template>
  <div>
    <slot />
  </div>
</template>

那麼,這個Child組件是什麼樣的?

咱們須要它從Parent組件獲取內容並將其提供給Grandchild組件,所以咱們將兩個不一樣的插槽鏈接在一塊兒。

// Child.vue
<template>
  <Grandchild>
    <slot />
  </Grandchild>
</template>

請記住,<slot />元素渲染出做爲插槽傳遞到組件的內容。 所以,咱們將從「Parent」中獲取該內容,而後將其渲染到「Grandchild」插槽中。

添加做用域插槽

與嵌套做用域插槽惟一不一樣的是,咱們還必須傳遞做用域數據。將其添加到v-for中,咱們如今獲得如下信息:

<template>
  <div>
    <slot v-bind:item="list[0]">
      <!-- Default -->
      {{ list[0] }}
    </slot>
    <v-for
      v-if="list.length > 1"
      :list="list.slice(1)"
    >
      <!-- Recursively pass down scoped slot -->
      <template v-slot="{ item }">
        <slot v-bind:item="item" />
      </template>
    </v-for>
  </div>
</template>

首先讓咱們看一下基本狀況。

若是沒有提供插槽,則默認<slot>元素內部的內容,並像之前同樣渲染list[0]。 可是若是咱們提供了一個slot,它會將其渲染出來,並經過slot做用域將列表項傳遞給父組件。

這裏的遞歸狀況相似。 若是咱們將插槽傳遞給v-for,它將在下一個v-for的插槽中進行渲染,所以咱們獲得了嵌套。 它還從做用域槽中獲取item並將其傳遞迴鏈。

如今,咱們這個組件僅使用template就能實現 v-for效果。

總結

咱們作了不少事情,終於瞭解瞭如何建立一個僅使用 template 就能實現v-for的效果。

本文主要內容:

  • 遞歸地表示列表
  • 遞歸組件
  • 嵌套槽和嵌套做用域槽

原文:https://stackoverflow.com/que...

代碼部署後可能存在的BUG無法實時知道,過後爲了解決這些BUG,花了大量的時間進行log 調試,這邊順便給你們推薦一個好用的BUG監控工具 Fundebug


交流

文章每週持續更新,能夠微信搜索「 大遷世界 」第一時間閱讀和催更(比博客早一到兩篇喲),本文 GitHub https://github.com/qq449245884/xiaozhi 已經收錄,整理了不少個人文檔,歡迎Star和完善,你們面試能夠參照考點複習,另外關注公衆號,後臺回覆福利,便可看到福利,你懂的。

相關文章
相關標籤/搜索