2

我正在尝试制作一个页面,该页面会将文本字符串(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, ($0, $1) => `<component v-bind:is="${$1.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 组件

4

1 回答 1

3

你不能这样做v-html

更新元素的 innerHTML。请注意,内容是作为纯 HTML 插入的——它们不会被编译为 Vue 模板。如果您发现自己尝试使用 v-html 编写模板,请尝试改用组件来重新考虑解决方案。

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

事实上,如果你想定义你的笔记块等,你可以在内部使用非动态组件。人。作为组件而不是数据项,但您肯定需要将容器作为动态组件,因为这是将文本数据转换为 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, ($0, $1) => `<component v-bind:is="${$1.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>

于 2018-11-29T18:09:24.100 回答