question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Allow a single slot to be rendered for multiple times

See original GitHub issue

What problem does this feature solve?

Currently if we render a slot for multiple times (eg. inside a v-for loop), we’ll get

Duplicate presence of slot "${name}" found in the same render tree - this will likely cause render errors.

I know it’s intentional to prevent render errors (like losing correct data binding) but consider the following use case: I have a v-breadcrumbs component which has a default item separator of a text node /, and I want to allows users to specify their own separators which can be anything, like an <v-icon> component.

Currently if I want to make it work, I have to define a scoped slot in the v-breadcrumbs component and bind nothing to it:

<slot name="sep" v-bind="{}">/</slot>

And component users must define slot-scope on it and not use anything from it:

<v-breadcrumbs>
  <v-icon slot="sep" slot-scope="_" name="angle-right"/>
</v-breadcrumbs>

And currently Vue is using slots as fallbacks for scoped slots with the same name. Whether the users can use a slot doesn’t rely on if they want data from slot scope, but on whether the slot is gonna be rendered for multiple times inside the component self, this may raise more confusion for our users (like #8175).

So why don’t we just get rid of such caveats and let a slot to be rendered more than once? We can clone them on duplication to prevent render errors as we already run the scoped slot function each time anyway. This makes the logic a lot simpler for users IMO: if we do not expect to use data from the slot scope, just use a slot, otherwise we’ll always have to declare slot-scope to create the binding.

In addition, this would make documenting the (scoped) slots of a component more consistent, we just declare the data structure for a slot scope and users can decide if they want some data to bind to the slot-scope and don’t need to care about how many times it will be rendered.

What does the proposed API look like?

No additional API needed, just clone the slot nodes upon render and remove the waring about duplicated slots.

It may be implemented in userland today in a quite hacky way, see: https://codesandbox.io/s/lp11y2wovz

I just tweaked the cloneVNode function from the Vue core a little bit and it seemed to be working as expected using render function (without losing reactivity and event binding). There maybe some other edge situations I missed so correct me if it’s not such trivial.

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Reactions:13
  • Comments:12 (6 by maintainers)

github_iconTop GitHub Comments

8reactions
Justineocommented, Dec 6, 2018

Resolved by 530ca1b2db315fbd0e360807b2031d26665c5d3d and shipped with vue@2.5.18-beta.0. Cheers! 🎉

0reactions
backbone87commented, Sep 28, 2018

another benefit of always using scopedSlots insteadof slots is lazy evaluation of slot content: Imagine a component with the following template loading(:while="!item") {{ item.name }} The loading comp wouldnt display the slot content until item becomes truthy, but “normal” slots are rendered eagerly causing errors despite the slot content not being displayed.

Read more comments on GitHub >

github_iconTop Results From Across the Web

How to use the <slot> element twice? - Stack Overflow
Essentially, what I want is a component that will first render the HTML code that I place within the component, and then I...
Read more >
Slots - Vue.js
There are times when it's useful to have multiple slot outlets in a single component. For example, in a <BaseLayout> component with the...
Read more >
Shadow DOM slots, composition
The first <slot> in shadow DOM that doesn't have a name is a “default” slot. It gets all nodes from the light DOM...
Read more >
Pass Multiple Children to a React Component with Slots
You need to create a reusable component. But the children prop won't cut it. This component needs to be able to accept multiple...
Read more >
Using templates and slots - Web Components | MDN
Slots are identified by their name attribute, and allow you to define placeholders in your template that can be filled with any markup...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found