做者: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,2,3]
傳遞到v-for
中進行渲染v-for
組件渲染1
,而後將[2,3]
傳遞到下一個v-for
進行渲染[2,3]
並渲染2
,而後將[3]
傳遞到下一個v-for
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>
一旦弄清楚瞭如何遞歸地嵌套插槽,就會對它癡迷同樣的感嘆:
首先,咱們將簡要介紹嵌套插槽的工做方式,而後介紹如何將它們合併到v-for
組件中。
假設咱們有三個組件:Parent
、Child
和Grandchild
。咱們但願傳遞來自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和完善,你們面試能夠參照考點複習,另外關注公衆號,後臺回覆福利,便可看到福利,你懂的。