用Vue组件动态替换文本字符串

Dynamically replaced text string with Vue component

我正在尝试制作一个页面,该页面会将文本字符串 (https://pastebin.com/Mp9sKy1A) 加载到页面中,然后用适当的组件替换 --FML-[componentName] 的任何实例。

因此,例如 --FML-[NoteBlock] 将自动替换为 NoteBlock 组件。

这是我目前所拥有的:

pureContent () {
      const c = this.content.replaced
      const re = new RegExp(`<p>--FML-\[(\w+)\]</p>`, 'g')
      return c.replace(re, ([=10=], ) => `<component v-bind:is="${.toLowerCase()}"></component>`)
    }

然后将输出放入以下模板中:

<template>
  <div>
    <site-header></site-header>
    <div class="wrapper">
      <side-bar></side-bar>
      <main class="container" v-html="pureContent()" />
    </div>
  </div>
</template>

它确实有点用。但是 component 部分并没有作为实际组件被引入,而是 <component> HTML 标记,这显然不是期望的结果。有没有办法让它按预期工作?

如果有人感兴趣,这里是完整的 SFC 文件:https://pastebin.com/yb4CJ1Ew

这是我目前得到的输出:

<main data-v-86dcc3c4="" class="container">
  <h1 id="creating-new-contexts">Creating new contexts</h1>
  <h2 id="section-title">Section Title</h2>
  <h3 id="section-subtitle-that-contains-additional-information">
    Section subtitle that contains additional information
  </h3>
  <p>
    Cillum ipsum ad veniam elit non. Sunt ea ut quis qui dolore id voluptate
    magna. Ex non commodo reprehenderit ipsum irure. Ad excepteur nulla ullamco
    et deserunt magna et sint reprehenderit sint esse commodo. Tempor duis anim
    nisi commodo incididunt ut ex et sunt laborum excepteur ea culpa laborum.
  </p>
  <component v-bind:is="noteblock"></component>
  <p>
    Officia esse Lorem ad duis dolore nostrud ex elit aliqua incididunt sint ad
    ex. Eiusmod do in ad aute nulla eiusmod tempor Lorem non. Qui sunt voluptate
    laborum mollit elit adipisicing minim dolore voluptate veniam incididunt
    proident ullamco. Ipsum est cupidatat occaecat pariatur ut aute.
  </p>
  <component v-bind:is="codeexample"></component>
  <component v-bind:is="propstable"></component>
</main>

<component> 标签应该是实际的 Vue 组件

You can't do it with v-html:

Updates the element’s innerHTML. Note that the contents are inserted as plain HTML - they will not be compiled as Vue templates. If you find yourself trying to compose templates using v-html, try to rethink the solution by using components instead.

您已经在使用动态组件,您只需要一个组件来控制它们(并在文档中绑定它们)。

事实上,如果您想定义笔记块,您可以在内部使用非动态组件,等。 al. 作为组件而不是数据项,但是你肯定需要容器是一个动态组件,因为这是将文本数据转换为 Vue 管理的唯一方法 DOM.

new Vue({
  el: '#app',
  data: {
    preContent: "<h1 id=\"creating-new-contexts\">Creating new contexts</h1>\n<h2 id=\"section-title\">Section Title</h2>\n<h3 id=\"section-subtitle-that-contains-additional-information\">Section subtitle that contains additional information</h3>\n<p>Cillum ipsum ad veniam elit non. Sunt ea ut quis qui dolore id voluptate magna. Ex non commodo reprehenderit ipsum irure. Ad excepteur nulla ullamco et deserunt magna et sint reprehenderit sint esse commodo. Tempor duis anim nisi commodo incididunt ut ex et sunt laborum excepteur ea culpa laborum.</p>\n<p>--FML-[NoteBlock]</p>\n<p>Officia esse Lorem ad duis dolore nostrud ex elit aliqua incididunt sint ad ex. Eiusmod do in ad aute nulla eiusmod tempor Lorem non. Qui sunt voluptate laborum mollit elit adipisicing minim dolore voluptate veniam incididunt proident ullamco. Ipsum est cupidatat occaecat pariatur ut aute.</p>\n<p>--FML-[CodeExample]</p>\n<p>--FML-[PropsTable]</p>\n"
  },
  computed: {
    pureContent() {
      const c = this.preContent;
      const re = new RegExp(`<p>--FML-\[(\w+)\]</p>`, 'g');

      return c.replace(re, ([=10=], ) => `<component v-bind:is="${.toLowerCase()}"></component>`);
    },
    postProcessSpec() {
      return {
        template: `<div>${this.pureContent}</div>`,
        data() {
          return {
            codeexample: {
              template: '<pre>This is the CODEEXAMPLE component</pre>'
            },
            noteblock: {
              template: '<div>This is the NOTEBLOCK component</div>'
            },
            propstable: {
              template: '<table border=1><th>PROPS TABLE!</th></table>'
            }
          }
        },
        components: {}
      };
    }
  }
});
<script src="https://unpkg.com/vue@latest/dist/vue.js"></script>
<div id="app">
  <component :is="postProcessSpec"></component>
</div>