Subscribe on changes!

useSlots().default not null

avatar
Apr 27th 2022

Version

3.2.33

Reproduction link

sfc.vuejs.org/

Steps to reproduce

the App component has a slot, and the v-if of the slot passed in by Child is false

What is expected?

I expected the console "slotDefault" is null

What is actually happening?

when I console.log "slotDefault" is not null

avatar
Apr 27th 2022
avatar
Apr 27th 2022

ok,thxNamed Slots can solve this problem

avatar
Apr 27th 2022

why the default slot can not work?

avatar
Apr 27th 2022

why the default slot can not work?

why white the slot in the App Component(root component) ?

avatar
Apr 27th 2022

I just use like this in the Parent Component log next line content const slotDefault = useSlots().default; console.log('slotDefault', slotDefault); App is right here Parent Component

avatar
Apr 27th 2022

image

avatar
Apr 27th 2022

in the Dialog Component log slot.default is not null,but just like your example ,use named slot can work,I want to know why?

avatar
Apr 27th 2022

in the Dialog Component log slot.default is not null,but just like your example ,use named slot can work,I want to know why?

this is name slot:

example

this is default slot:

example

avatar
Apr 27th 2022

You can use the "named slot" pattern with the default slot as well:

<Child>
  <template v-slot:default v-if="someCondition">

  </template>
</Child>
avatar
Apr 27th 2022

I just want to know why use default slot the console in my Dialog component is not null image

avatar
Apr 27th 2022

Because the v-if, when being false, leaves a placeholder in the vdom so it can later, when its true, be replaced with the actual content.

A similar thing happens when you have a v-for loop that has zero items - it still creates a Fragment vnode.

avatar
Apr 27th 2022

I just want to know why use default slot the console in my Dialog component is not null image

the code

<template v-if="false">App</template>

is also a vnode.

image

image

image

avatar
Apr 27th 2022

why the named slot did not leave vnode?

avatar
Apr 27th 2022

Because the v-if, when being false, leaves a placeholder in the vdom so it can later, when its true, be replaced with the actual content.

A similar thing happens when you have a v-for loop that has zero items - it still creates a Fragment vnode.

why the named slot did not leave vnode?

avatar
Apr 27th 2022

Because the v-if is on the <template v-slot:name>, instead of inside of the slot content

avatar
Apr 27th 2022

I don't think you understand me 1:<template #default> <div v-if="false"/> </template> 2:<template #name> <div v-if="false"/> </template> Both of the above:the first one slot.default is not null,the second slot.name is null I just want to know why the vnode work on defaut slot,but not work on the named slot

avatar
Apr 27th 2022

both variations you show here behave absolutely identical.The difference is between <Child v-slot:default> and <template v-slot:default>.

If you want me to explain more, please provide a playground with a demo of the exact problem you are asking about.

avatar
Apr 27th 2022

I don't think you understand me 1:<template #default> <div v-if="false"/> </template> 2:<template #name> <div v-if="false"/> </template> Both of the above:the first one slot.default is not null,the second slot.name is null I just want to know why the vnode work on defaut slot,but not work on the named slot

Let me show some example:

  1. <template #name> <div v-if="false"/> </template>

slot.name is not null

  1. <template #default> <div v-if="false"/> </template>

slot.default is not null

avatar
Apr 27th 2022

the parent Component is like this <template> <slot v-if="slotDefault"></slot> </template> <script> import {useSlots } from 'vue' const slotDefault = useSlots().default; console.log('slotDefault', slotDefault); // if use deafult slot log is not null,but use named slot log is null </script>

avatar
Apr 27th 2022

App.vue Dialog.vue image

defaut is not undefined, header as named slot is undefined

avatar
Apr 27th 2022

App.vue Dialog.vue image

defaut is not undefined, header as named slot is undefined

Example

image

The default slot is handled differently from the name slot:

<script setup name="App">
import Dialog from './Dialog.vue'
</script>

<template>
<Dialog>
    <template v-if="false"></template>
  <template #header v-if="false"></template>
  <template #main v-if="false"></template>
</Dialog>
</template>

I recommend you to look at the compiled code, copy the code to the vscode and formate it, you will have a deeper understanding

For your example compile to:

image

so name slot is undefined

/* Analyzed bindings: {
  "Dialog": "setup-const"
} */
import {
  Fragment as _Fragment,
  openBlock as _openBlock,
  createElementBlock as _createElementBlock,
  createCommentVNode as _createCommentVNode,
  withCtx as _withCtx,
  createSlots as _createSlots,
  createBlock as _createBlock,
} from 'vue'

import Dialog from './Dialog.vue'

const __sfc__ = {
  setup(__props) {
    return (_ctx, _cache) => {
      return (
        _openBlock(),
        _createBlock(
          Dialog,
          null,
          _createSlots(
            //  default slot
            {
              default: _withCtx(() => [
                false
                  ? (_openBlock(), _createElementBlock(_Fragment, { key: 0 }, [], 64 /* STABLE_FRAGMENT */))
                  : _createCommentVNode('v-if', true),
              ]),
              _: 2 /* DYNAMIC */,
            },
            // name slot
            [
              // the value is undefined
              false
                ? {
                    name: 'header',
                    fn: _withCtx(() => []),
                  }
                : undefined,
              // the value is undefined
              false
                ? {
                    name: 'main',
                    fn: _withCtx(() => []),
                  }
                : undefined,
            ]
          ),
          1024 /* DYNAMIC_SLOTS */
        )
      )
    }
  },
}
__sfc__.__file = 'App.vue'
export default __sfc__
avatar
Apr 27th 2022

<template v-if="..."> != <template v-slot:default v-if="....">

the former is just a way of using v-if, unrelated to slots. so you basically just passed <div v-if> to the default slot again.

The latter is how you can to define a default slot alongside other named slots.

You can learn more in this section of the docs: https://vuejs.org/guide/components/slots.html#named-slots

avatar
Apr 27th 2022