How to use nested slots in Vue (including scope slots)

Posted May 26, 20205 min read

Author:Michael Thiessen
Translator:Xiaozhi
Source:medium

Like it and see it again, develop a habit

This article GitHub https://github.com/qq44924588... has been included, more classification of previous high praise articles, also sorted out A lot of my documents, and tutorial materials. Welcome Star and Perfect, everyone can refer to the test site for review in the interview, I hope we have something together.

Recently I figured out how to implement nested slots recursively, including how to use scoped slots. The reason is that I wanted to see if I could build a copy of the v-for command but only use the template component.

It also supports slots and scope slots, and it can also support named slots. We can use it like this:

<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>

The first will print the list normally, while the second will wrap each item in the <strong> tag.

This is not a very useful component, but the most can be learned from it, let's take a look.

Loop-free

Normally, when we want to render a list of elements or components, we can use the v-for command, but this time we want to get rid of it completely.

So, how do we render the list of items without using loops? Just use recursive.

We can use recursion to render the list of items. The process is not complicated, let's see how to do it.

Recursively represents a list

One of my favorite courses in college is "Programming Language Concepts" .

For me, the most interesting part is to explore functional programming and logic programming, and understand the difference with imperative programming(Javascript and the most popular language is imperative programming).

This course gave me a real understanding of how to use recursion, because in pure functional languages, everything is recursive. Anyway, from that course I learned that I can use recursion to represent a list.

Unlike using arrays, each list is a value(head) and another list(tail).

[head, tail]

For example, to represent the list [1,2,3], it can be expressed recursively as:

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

We have to end the list somehow, so we use null instead of another array(an empty array can also be used).

Seeing this, you may understand that we can use this concept and apply it to our components. Instead, we will recursively nest components to represent lists.

We will eventually render such content. Note the nested structure of our "list":

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

Admittedly, this is not exactly the same as v-for rendering, but this is not the focus of this exercise.

Build component

First, we will solve the problem of recursively rendering the list of items.

Use recursion to render lists

This time we use a normal array instead of the recursive list introduced earlier:

[1, 2, 3]

There are two cases to be discussed here:

  • Basic situation-the first item in the rendering list
  • Recursive situation-render the project and then immerse in the next list

We pass [1,2,3] to v-for

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

We want to get the first item in the list, which is 1, and display it

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

Now, the component will render 1, as we expected.

But we cannot just render the first value and stop. We need to render the value and then also render the rest of the list:

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

Instead of passing the entire list array, we delete the first item and pass the new array. We have printed the first item, so there is no need to keep it.

The order is this:

  1. We pass [1,2,3] to v-for for rendering
  2. Our v-for component renders 1, then passes [2,3] to the next v-for for rendering
  3. Take [2,3] and render 2, then pass [3]to the next v-for
  4. The last v-for component renders 3, we have printed out the list!

Now, the structure of our Vue application looks like this:

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

As you can see, we have several v-for components, which are nested with each other. One last thing, we need to stop recursion

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

Finally, after rendering all items, we need to stop the recursive operation.

Recursively nested slots

Now, the component works properly, but we also want it to be used with slots in scope, because this way you can customize the way each item is rendered:

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

Nested slots

Once you figure out how to nest the slot recursively, you will lament the same obsession:

  • Nested n-level slots
  • Recursive slots
  • Packaging components convert one slot into multiple slots

First, we will briefly introduce how nested slots work, and then describe how to incorporate them into the v-for component.

Suppose we have three components:Parent, Child and Grandchild. We want to pass some content from the Parent component and render it in the Grandchild component.

Starting from Parent, we pass some content:

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

We do some things in the Child component, which will be introduced later. Then our Grandchild component gets the slot and renders the content:

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

So, what does this Child component look like?

We need it to get content from the Parent component and provide it to the Grandchild component, so we connect two different slots together.

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

Remember, the <slot /> element renders the content passed to the component as a slot. Therefore, we will get the content from the "Parent" and then render it into the "Grandchild" slot.

Add scope slots

The only difference from nested scope slots is that we must also pass scope data. Adding it to v-for, we now get the following information:

<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>

Let us first look at the basic situation.

If no slot is provided, the content inside the <slot> element is defaulted, and list [0] is rendered as before. But if we provide a slot, it will render it and pass the list item to the parent component through the slot scope.

The recursion situation here is similar. If we pass the slot to v-for, it will be rendered in the next v-for slot, so we get nested. It also takes the item from the scope slot and passes it back to the chain.

Now, our component can only use template to achieve v-for effect.

to sum up

We did a lot of things, and finally learned how to create a v-for effect using only template.

The main content of this article:

  • Recursively represent a list
  • Recursive components
  • Nesting slots and nesting scope slots

Original: https://stackoverflow.com/que...

Bugs that may exist after the code is deployed cannot be known in real time. In order to solve these bugs afterwards, a lot of time is spent on log debugging. Here, I recommend a useful BUG monitoring tool Fundebug .


communicate with

The article is continuously updated every week, you can read WeChat search "Great Move World" for the first time to read and reminder(one or two earlier than the blog), this article GitHub https://github.com/qq449245884/xiaozhi has been included, a lot of my documents have been compiled, welcome Star and perfect, everyone can refer to the test site for review during the interview, and pay attention to the public number, reply welfare in the background, you can see the benefits ,You know.