How to handle slots in Vue3 and Storybook 7
P粉504920992
2023-08-26 00:23:54
<p>I'm trying to pass a component (UIButton) as a slot in another component (UICard) in the ButtonAsSlot story. </p>
<p>In the ButtonAsSlot story, I pass <code>default: '<uibutton v-bind="{type: 'button', isDisabled: false,variant: 'primary', label: 'test ',} ">',</uibutton></code> as args.default, so it will be passed in the slot. </p>
<p>If I could pass an existing story (e.g. <code>default: '<uibutton v-bind="ImportedStory.args">'</uibutton></code>), then That would be great. However, this doesn't work. </p>
<p>I tried the following but got the error <code>Error: Unexpected identifier 'object' </code> on Storybook. </p>
<pre class="brush:php;toolbar:false;">const disabledArgs = ImportedStory.args
export const ButtonAsSlot: Story = {
...Playground,
render: (args, { argTypes }) => ({
components: { UICard, UIButton },
props: Object.keys(argTypes),
setup() {
return {
...args,
}
},
template: `
<UICard v-bind="args">
<template v-if="$props.default" v-slot>
<p>↓Content of slot displayed below</p>
${args.default}
</template>
</UICard>
`,
}),
args: {
...Playground.args,
default: `<UIButton v-bind="${disabledArgs}" />`,
},</pre>
<p>How can I pass a component using an existing story in a parameter and set it in a slot? </p>
<p>I am using Vue3. code show as below.</p>
<p>--Card.stories.ts</p>
<pre class="brush:php;toolbar:false;">import type { Meta, StoryObj } from '@storybook/vue3'
import UICard from './Card.vue'
import UIButton from '~/components/Clickable/Button.vue'
import { setDefaultProps } from '~/.storybook/utils'
const meta: Meta<typeof UICard> = {
title: 'Elements/Card',
component: UICard,
tags: ['autodocs'],
}
export default meta
type Story = StoryObj<typeof UICard>
export const Playground: Story = {
story: {
name: 'Default',
},
render: (args, { argTypes }) => ({
components: { UICard },
props: Object.keys(argTypes),
setup() {
return {
...args,
}
},
template: `
<UICard v-bind="args">
<template v-if="$props.default" v-slot>
${args.default}
</template>
</UICard>
`,
}),
}
setDefaultProps(Playground, UICard)
export const ButtonAsSlot: Story = {
...Playground,
story: {
name: 'Button as slots',
},
render: (args, { argTypes }) => ({
components: { UICard, UIButton },
props: Object.keys(argTypes),
setup() {
return {
...args,
}
},
template: `
<UICard v-bind="args">
<template v-if="$props.default" v-slot>
<p>↓Content of slot displayed below</p>
${args.default}
</template>
</UICard>
`,
}),
args: {
...Playground.args,
default: '<UIButton v-bind="{type: 'button', isDisabled: false, variant: 'primary', label: 'test',}" />',
},
}</pre>
<p><br /></p>
Finally I wrote the code like this and it worked.