【发布时间】:2021-12-31 03:32:35
【问题描述】:
所以,我从一个可变的 HTML 字符串开始,它是我的用户在 RichText 编辑器中创建的 UI 模板(保存到磁盘上的 XML 文件中)。它总是有效的 XHTML。 XML 可以像这样简单:
<div>{{FORM_PLACEHOLDER}}</div>
或者像这样复杂:
<div id="user-customized-content">
<h1 class="display-1">Customized Header</h1>
<p class="mb-3">
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt
ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco
<strong>laboris nisi ut aliquip</strong> ex ea commodo consequat. Duis aute irure dolor in
reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint
occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</p>
<div class="alert alert-info">
<p>Laboris nisi ut <em>aliquip</em> ex ea commodo consequat</p>
</div>
<h3 class="display-4">Lorem ipsum dolor:</h3>
<form>{{FORM_PLACEHOLDER}}</form>
<p class="mb-3">
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim
id est laborum.
</p>
</div>
但它会总是在 XML 字符串的某处有 {{FORM_PLACEHOLDER}}。这将指定 HTML 表单在 HTML Wrapper 代码中的确切位置。
在我的 SPA 应用程序中(我们使用 Vue.js,但我认为使用什么框架/库并不重要),我通过 axios 调用检索 HTML,然后我需要将 XHTML 写入我的交互式表单周围的页面(示例如下所示)。
在 Vue.js 中,我们为此使用“插槽”。因此,父组件将包含表单,其子组件(在下面的示例中为HtmlWrapper)将有一个环绕表单的插槽。
<template>
<HtmlWrapper>
Name: <input type="text" name="Name" v-validate="'required'" /><br />
Email: <input type="email" name="Email" /><br />
<button @click="dofunction()">Submit Form</button>
</HtmlWrapper>
</template>
<script>
import HtmlWrapper from "@/components/HtmlWrapper.vue"
</script>
我已经尝试过但不起作用的方法:
- 在占位符和injecting the HTML 直接在表单字段的上方和下方拆分 HTML 字符串。这不起作用,因为如果使用 Vue 或 JS 将它们添加到 DOM,顶部的标签会自动关闭。
-
Converting the XML string to
XmlDocumentin C# and then serializing it to JSON 传递给 javascript。这很好用,使我能够遍历 json 以围绕<slot></slot>tag 构建 HTML,但随后我意识到相同类型的多个 HTML 标记会被分组到数组中,这会破坏它们在页面上出现的顺序。
我认为需要发生的是我需要遍历 XHTML 字符串,递归地逐个标记,并在页面上创建每个 javascript 元素,然后当我点击占位符时,我创建插槽那时(这在 Vue.js 中很容易做到:this.$slots.default)。如果我不需要(在此过程中犯下所有最初的错误),我宁愿不重新发明轮子,所以如果有一种方法已经存在并且可用或某种组件可以做到这一点,那就太好了。否则,为我指明正确的方向将是无价的。 TIA。
【问题讨论】:
-
我怀疑 Vue 将发挥比您预期更大的作用。但是您可能会使用 DOMParser API 来加载 html blob。纯 javascript 中的粗略示例可能类似于 this
-
@David 我认为您可能是正确的,因为 Vue 可能需要发挥更大的作用,但我希望可以利用这一点。我需要使用这种方法渲染到页面:v3.vuejs.org/guide/render-function.html#the-virtual-dom-tree 类似这样的东西:
render() { const slot = this.$slots.default ? this.$slots.default() : []; const doc = new DOMParser().parseFromString(this.htmlData.replace('{{FORM_PLACEHOLDER}}', slot),'text/html'); return h('content', {}, doc); },显然,由于 doc 和 slot 类型,这不起作用。 -
我的 Vue 知识非常有限,但也许你可以使用异步组件来异步加载用户模板,注入一个 slot 标签然后渲染它。我做了一个快速example here
-
@David 可以使用未在 main.js 中全局注册的组件来完成吗?我无法让它工作。
-
听起来你只想动态创建一个组件。输出 HTML 以便呈现。然后调用另一个事件,以便您可以创建元素并替换占位符。 css-tricks.com/…
标签: javascript json vue.js xhtml