【发布时间】:2021-06-17 09:55:14
【问题描述】:
我正在 Vue 3 中开发一个动态仪表板,用户可以在其中为他们想要渲染的部分指定简单的类似 XML 的模板。
我希望 XML 中与特定 Vue 组件名称匹配的节点呈现为 Vue 组件,而其他节点应呈现为普通 HTML。
例如,一个 XML 模板可能如下所示:
<Dashboard>
<Elements>
<div class="title">Switches</div>
<Switches device="kitchen-bulb" />
</Elements>
</Dashboard>
<Elements> 内部的 <div> 应该呈现为普通 HTML(我已经通过利用 <slot> 并将节点内容传递给 <Elements> 组件上的 v-html 实现了这一点),而 @ 987654329@ 与特定导入的 Vue 组件的名称匹配,应呈现为 Vue 组件 - 在本例中,使用从模板传递的 device 属性。
现在的代码如下所示:
/// index.js
import Switch from './Switch'
export default {
Switch,
}
/// Elements.vue
<template>
<div class="elements">
<div class="container" v-html="content" />
</div>
</template>
<script>
import elements from './index'
export default {
name: "Elements",
props: {
content: {
type: String,
},
},
mounted() {
const content = new DOMParser()
.parseFromString(`<div>${this.content}</div>`, 'text/html')
.childNodes[0]
Object.entries(elements).forEach(([name, element]) => {
this.$options.components[name] = element
const nodes = content.getElementsByTagName(name);
[...nodes].forEach((node) => {
const renderedComponent = magicStringToRenderedHTMLStringOrDOM(element, node)
node.parentElement.replaceChild(renderedComponent, node)
})
})
this.content = content.childNodes[0].innerHTML
},
}
</script>
content是<Elements>的节点内容,由其父级传递给组件。
我需要的是填充 magicStringToRenderedHTMLStringOrDOM 调用的东西,给定 Vue 组件定义、节点表示和属性,呈现 Vue 组件,我可以简单地在 content 中替换并使用 v-html 呈现。
我知道 Vue 2 曾经提供something similar with Vue.compile。我发现的唯一一个明显做类似事情的 Vue 3 函数是 createRenderer,但我没有找到很多如何使用它的示例。
【问题讨论】:
标签: javascript vue.js vuejs3