diff --git a/code/renderers/vue/src/docs/sourceDecorator.ts b/code/renderers/vue/src/docs/sourceDecorator.ts
index 24c4fe3c4ddb..becc96802860 100644
--- a/code/renderers/vue/src/docs/sourceDecorator.ts
+++ b/code/renderers/vue/src/docs/sourceDecorator.ts
@@ -4,7 +4,7 @@
import { addons } from '@storybook/preview-api';
import { logger } from '@storybook/client-logger';
import { SourceType, SNIPPET_RENDERED } from '@storybook/docs-tools';
-import type { ComponentOptions } from 'vue';
+import { type ComponentOptions } from 'vue';
import type Vue from 'vue';
import type { StoryContext } from '../types';
@@ -24,46 +24,47 @@ export const skipSourceRender = (context: StoryContext) => {
export const sourceDecorator = (storyFn: any, context: StoryContext) => {
const story = storyFn();
+ const source = '';
// See ../react/jsxDecorator.tsx
- if (skipSourceRender(context)) {
+ const skip = skipSourceRender(context);
+ if (skip) {
return story;
}
const channel = addons.getChannel();
const storyComponent = getStoryComponent(story.options.STORYBOOK_WRAPS);
+ const generateSource = (vueInstance: any) => {
+ try {
+ // console.log('updateSource():', vueInstance.$vnode);
+ const storyNode = lookupStoryInstance(vueInstance, storyComponent);
+ if (!storyNode) {
+ logger.warn(`Failed to find story component in the rendered tree: ${storyComponent}`);
+ return;
+ }
+ // eslint-disable-next-line no-param-reassign
+ vueInstance.source = vnodeToString(storyNode._vnode);
+ } catch (e) {
+ logger.warn(`Failed to generate dynamic story source: ${e}`);
+ }
+ };
return {
components: {
Story: story,
},
- // We need to wait until the wrapper component to be mounted so Vue runtime
- // struct VNode tree. We get `this._vnode == null` if switch to `created`
- // lifecycle hook.
+ data() {
+ return { source };
+ },
+ updated() {
+ generateSource(this);
+ },
mounted() {
- // Theoretically this does not happens but we need to check it.
- // @ts-expect-error TS says it is called $vnode
- if (!this._vnode) {
- return;
- }
-
- try {
- const storyNode = lookupStoryInstance(this, storyComponent);
-
- // @ts-expect-error TS says it is called $vnode
- const code = vnodeToString(storyNode._vnode);
-
- const { id, unmappedArgs } = context;
- channel.emit(SNIPPET_RENDERED, {
- id,
- args: unmappedArgs,
- source: `${code}`,
- format: 'vue',
- });
- } catch (e) {
- logger.warn(`Failed to generate dynamic story source: ${e}`);
- }
+ this.$watch('source', (val) =>
+ channel.emit(SNIPPET_RENDERED, context.id, `${val}`, 'vue')
+ );
+ generateSource(this);
},
template: '',
} as ComponentOptions & ThisType;