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.

`this.$scopedSlots.default()` returns VNode directly or array of VNodes depending on content

See original GitHub issue

Version

2.5.16

Reproduction link

https://jsfiddle.net/50wL7mdz/323954/

Steps to reproduce

  1. Create a component that uses a render function to return some parent element with this.$scopedSlots.default({}) as the children.
  2. Create an instance of that component that passes multiple elements to the scoped slot and see this.$scopedSlots.default({}) return an array.
  3. Create an instance of that component that passes a single element to the scoped slot and see this.$scopedSlots.default({}) return a VNode, not an array with a single VNode in it.

What is expected?

this.$scopedSlots.default({}) should always return an array of VNodes, even if there’s only one VNode in the array.

This is how this.$slots.default behaves.

What is actually happening?

this.$scopedSlots.default({}) returns mixed types: an array when there are multiple elements in the slot, or a direct VNode instance if there is only a single child.


This is inconsistent with how regular slots behave in render functions, and means any render function component rendering scoped slots as children needs to type check the result of invoking the slot to decide if it needs to be wrapped in an array:

render(h) {
  const children = this.$scopedSlots.default({})
  return h('div', {}, Array.isArray(children) ? children : [children])
}

Contrast that with regular slots where it is always safe to pass the slot as a child because it is always an array:

render(h) {
  return h('div', {}, this.$slots.default)
}

It’s a bummer because although this is pretty easy to classify as a bug, it would be a breaking change for a lot of people using scoped slots to write components that use the default scoped slot as their root element:

render() {
  return this.$scopedSlots.default({ someDataThisComponentIsResponsibleFor })
}

If this bug were fixed, anyone with a component like that would need to re-write it like this:

render() {
  return this.$scopedSlots.default({ someDataThisComponentIsResponsibleFor })[0]
}

If this isn’t a bug and is by design, I’d love to better understand the reasoning!

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Reactions:6
  • Comments:11 (8 by maintainers)

github_iconTop GitHub Comments

14reactions
yyx990803commented, Apr 20, 2018

I was just thinking about this today. I think it makes more sense to make it consistent and always return an Array.

1reaction
yyx990803commented, Dec 26, 2018

Implemented in c7c13c2.

Also made it possible to return an Array of a single VNode from render functions - thus avoiding breaking the usage of directly returning a scoped slot.

Read more comments on GitHub >

github_iconTop Results From Across the Web

22. Render Functions & JSX - Vue.js 2 - W3cubDocs
children : An array of the VNode children; slots : A function returning a slots object; scopedSlots : (2.6.0+) An object that exposes...
Read more >
Do Vue.js render functions allow return of an array of VNodes?
$scopedSlots.default() returned both a VNode or an array of VNodes depending on the content. The main argument was that this is inconsistent ...
Read more >
Render Functions | Vue GWT - GitHub Pages
When you get started with a component that just generates a heading based on the ... And access scoped slots as functions that...
Read more >
Vue - Render Functions and JSX - w3resource
slots.default // array of children ) }, props: { level: { type: ... We can access scoped slots as functions that return VNodes...
Read more >
Team:BNUZ-China/scripts/vue - iGEM 2021
Convert a value to a string that is actually rendered. */ function toString (val) { return val == null ? : Array.isArray(val) ||...
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