做者: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和完善,你们面试能够参照考点复习,另外关注公众号,后台回复福利,便可看到福利,你懂的。