Problem: <pre>{{ $slots.title() }}</pre>
is not printing out the expected object.
My parent component
<script setup>
import { ref } from 'vue'
import Modal from '@/components/Modal.vue'
import { btnStyleDark } from '@/styles/tailwindStyles'
const showModal = ref(false)
</script>
<template>
<div>
<h1>Modals</h1>
<button @click="showModal = true" :class="btnStyleDark">Show Modal</button>
<Modal v-if="showModal" @close="showModal = false" :btn-style="btnStyleDark">
<template #title>My new title</template>
<p>
Lorem, ipsum dolor sit amet consectetur adipisicing elit. Vel tempora quibusdam tenetur,
debitis autem fugit a nesciunt mollitia ipsa inventore nostrum perspiciatis neque dolor id
magnam facere eum similique? Adipisci.
</p>
</Modal>
</div>
</template>
My child component
<script setup>
import { defineProps, defineEmits } from 'vue'
const props = defineProps({
btnStyle: String,
})
const emit = defineEmits(['close'])
</script>
<template>
<teleport to="#modals-container">
<div class="modal z-10 absolute top-0 left-0 w-full h-full p-10 bg-yellow-50">
<h1><slot name="title" /></h1>
<slot />
<pre>{{ $slots.title() }}</pre>
<button :class="btnStyle" @click="$emit('close')">Hide modal</button>
</div>
</teleport>
</template>
Error in chrome:
TypeError: Converting circular structure to JSON --> starting at object with constructor 'Object' | property 'vnode' -> object with constructor 'Object' --- property 'component' closes the circle at JSON.stringify () at toDisplayString (chunk-U6BEPC57.js?v=60065120:256:154)
If I remove the ()
from <pre>{{ $slots.title() }}</pre>
inside the child I am able to see this printed in the <pre>
tag on the page without an error:
However this data does not tell me anything and also does not match the data that is printed out from this course video:
Using the useSlots
import
This produces the same error, but the first console.log does work!
<script setup>
import { defineProps, defineEmits, useSlots, onMounted } from 'vue'
const props = defineProps({
btnStyle: String,
})
const emit = defineEmits(['close'])
const slots = useSlots()
console.log(slots.title())
onMounted(() => {
console.log(slots)
})
</script>
<template>
<teleport to="#modals-container">
<div class="modal z-10 absolute top-0 left-0 w-full h-full p-10 bg-yellow-50">
<h1><slot name="title" /></h1>
<slot />
<pre>{{ $slots.title() }}</pre>
<!-- <pre>{{ slots.title ? slots.title()[0] : '' }}</pre> -->
<button :class="btnStyle" @click="$emit('close')">Hide modal</button>
</div>
</teleport>
</template>
I also tried <pre>{{ slots.title() }}</pre>
without the $
and this still throws the error.
It seems it doesn't like to handle null values when it needs to display.
I use const slots = useSlots();
<div v-for="(value, key) in slots.title()[0]" :key="key">
<strong>{{ key.toString() }}:</strong>
{{ value ? value.toString() : "null" }}
</div>`
In my test phase, I created a simple function:
<button @click="close">Hide modal</button>
function close() {
console.log(slots.title()[0]);
emit("close");
}
And I got what you show in the udemy screenshot.
Little Hint to finish: I just noticed in your code that with Vue3, you declare the emit event, so you have to remove the '$' => @click="emit('close')"