Skip to content

Commit 67a966e

Browse files
committed
fix(ContentRendererMarkdown): recreate vNodes in render function
1 parent 9258e5c commit 67a966e

File tree

1 file changed

+23
-39
lines changed

1 file changed

+23
-39
lines changed

src/runtime/components/ContentRendererMarkdown.vue

Lines changed: 23 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import { useRuntimeConfig, useRoute } from '#app'
1010
import type { MarkdownNode, ParsedContentMeta } from '../types'
1111
1212
type CreateElement = typeof h
13-
type ContentVNode = VNode | string
1413
1514
/**
1615
* Default slot name
@@ -96,27 +95,19 @@ export default defineComponent({
9695
// Resolve component if it's a Vue component
9796
component = resolveVueComponent(component as string)
9897
99-
// Process children
100-
const children = (body.children || []).map(child => renderNode(child, h, meta))
101-
10298
// Return Vue component
10399
return h(
104-
component as any,
105-
{
106-
...meta.component?.props,
107-
...this.$attrs
108-
},
109-
{
110-
default: createSlotFunction(children)
111-
}
100+
component as any,
101+
{ ...meta.component?.props, ...this.$attrs },
102+
renderSlots(body, h, meta, meta)
112103
)
113104
}
114105
})
115106
116107
/**
117108
* Render a markdown node
118109
*/
119-
function renderNode (node: MarkdownNode, h: CreateElement, documentMeta: ParsedContentMeta, parentScope: any = {}): ContentVNode {
110+
function renderNode (node: MarkdownNode, h: CreateElement, documentMeta: ParsedContentMeta, parentScope: any = {}): VNode {
120111
/**
121112
* Render Text node
122113
*/
@@ -138,14 +129,15 @@ function renderNode (node: MarkdownNode, h: CreateElement, documentMeta: ParsedC
138129
}
139130
140131
const props = propsToData(node, documentMeta)
132+
141133
return h(
142134
component as any,
143135
props,
144136
renderSlots(node, h, documentMeta, { ...parentScope, ...props })
145137
)
146138
}
147139
148-
function renderBinding (node: MarkdownNode, h: CreateElement, documentMeta: ParsedContentMeta, parentScope: any = {}): ContentVNode {
140+
function renderBinding (node: MarkdownNode, h: CreateElement, documentMeta: ParsedContentMeta, parentScope: any = {}): VNode {
149141
const data = {
150142
...parentScope,
151143
$route: () => useRoute(),
@@ -171,31 +163,37 @@ function renderBinding (node: MarkdownNode, h: CreateElement, documentMeta: Pars
171163
/**
172164
* Create slots from `node` template children.
173165
*/
174-
function renderSlots (node: MarkdownNode, h: CreateElement, documentMeta: ParsedContentMeta, parentProps: any): ContentVNode[] {
166+
function renderSlots (node: MarkdownNode, h: CreateElement, documentMeta: ParsedContentMeta, parentProps: any): Record<string, () => VNode[]> {
175167
const children: MarkdownNode[] = node.children || []
176168
177-
const slots: Record<string, Array<VNode | string>> = children.reduce((data, node) => {
169+
const slotNodes: Record<string, MarkdownNode[]> = children.reduce((data, node) => {
178170
if (!isTemplate(node)) {
179-
data[DEFAULT_SLOT].push(renderNode(node, h, documentMeta, parentProps))
180-
return data
181-
}
182-
183-
if (isDefaultTemplate(node)) {
184-
data[DEFAULT_SLOT].push(...(node.children || []).map(child => renderNode(child, h, documentMeta, parentProps)))
171+
data[DEFAULT_SLOT].push(node)
185172
return data
186173
}
187174
188175
const slotName = getSlotName(node)
189-
data[slotName] = (node.children || []).map(child => renderNode(child, h, documentMeta, parentProps))
176+
data[slotName] = data[slotName] || []
177+
// Append children to slot
178+
data[slotName].push(...(node.children || []))
190179
191180
return data
192181
}, {
193182
[DEFAULT_SLOT]: [] as any[]
194183
})
195184
196-
const slotEntries = Object.entries(slots).map(([name, vDom]) => ([name, createSlotFunction(vDom)]))
185+
const slots = Object.entries(slotNodes).reduce((slots, [name, children]) => {
186+
if (!children.length) { return slots }
187+
188+
slots[name] = () => {
189+
const vNodes = children.map(child => renderNode(child, h, documentMeta, parentProps))
190+
return mergeTextNodes(vNodes)
191+
}
192+
193+
return slots
194+
}, {} as Record<string, () => VNode[]>)
197195
198-
return Object.fromEntries(slotEntries)
196+
return slots
199197
}
200198
201199
/**
@@ -344,20 +342,6 @@ function getSlotName (node: MarkdownNode) {
344342
return name || DEFAULT_SLOT
345343
}
346344
347-
/**
348-
* Create a factory function if there is a node in the list
349-
*/
350-
function createSlotFunction (nodes: Array<VNode | string>) {
351-
return (nodes.length ? () => mergeTextNodes(nodes as VNode[]) : undefined)
352-
}
353-
354-
/**
355-
* Check if node is root
356-
*/
357-
function isDefaultTemplate (node: MarkdownNode) {
358-
return isTemplate(node) && getSlotName(node) === DEFAULT_SLOT
359-
}
360-
361345
/**
362346
* Check if node is Vue template tag
363347
*/

0 commit comments

Comments
 (0)