使用Vue组件动态替换文本字符串 [英] Dynamically replaced text string with Vue component

查看:298
本文介绍了使用Vue组件动态替换文本字符串的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm attempting to make a page which will load a text string (https://pastebin.com/Mp9sKy1A) into a page and then replace any instance of --FML-[componentName] with the appropriate component.

所以例如 - FML- [NoteBlock] 将自动替换为 NoteBlock 组件。

So for example --FML-[NoteBlock] would be automatically replaced with the NoteBlock component.

这是我到目前为止所拥有的:

This is what I have so far:

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>`)
    }

输出将被放入以下模板中:

The output will then be placed into the following template:

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

它实际上有点工作。但是组件部分不是作为实际组件引入的,而是< component> HTML标记,这显然不是理想的结果。有没有办法使它按预期工作?

It actually sort of works. However the component part isn't being pulled in as an actual component, rather a <component> HTML tag, which obviously isn't the desired result. Is there a way to make it work as desired?

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

Here is the full SFC file if anyone is interested: https://pastebin.com/yb4CJ1Ew

这是我目前得到的输出:

This is the output I am currently getting:

<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组件

The <component> tags should be actual Vue components

推荐答案

你不能用 v-html 来做:


更新元素的innerHTML。请注意,内容以纯HTML格式插入
- 它们不会被编译为Vue模板。如果您
发现自己试图使用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.

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

You're already using dynamic components, you just need One Component To Rule Them All (and in the document bind them).

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

You could, in fact, use non-dynamic components internally, if you wanted to define your noteblock, et. al. as components rather than data items, but you definitely need the container to be a dynamic component, as that's the only way you can turn text data into Vue-managed 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>

这篇关于使用Vue组件动态替换文本字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆