Динамически заменяемая текстовая строка с компонентом Vue - PullRequest
0 голосов
/ 29 ноября 2018

Я пытаюсь создать страницу, которая будет загружать текстовую строку (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

1 Ответ

0 голосов
/ 29 ноября 2018

Вы не можете сделать это с v-html:

Обновляет innerHTML элемента.Обратите внимание, что содержимое вставляется в виде обычного HTML - оно не будет скомпилировано как шаблоны Vue.Если вы пытаетесь создавать шаблоны с использованием v-html, попробуйте переосмыслить решение, используя вместо этого компоненты.

Вы уже используете динамические компоненты, вам просто нужен один компонент, чтобы управлять ими всеми (и в документе свяжите их).

Фактически, вы можете использовать нединамические компоненты для внутреннего использования, если хотите определить свой блокнот, et.al. как компоненты, а не элементы данных, но вам определенно нужно, чтобы контейнер был динамическим компонентом, поскольку это единственный способ превратить текстовые данные в управляемый Vue DOM.

new Vue({
  el: '#app',
  data: {
    preContent: "Creating new contexts\nSection Title\nSection subtitle that contains additional information\nCillum 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.\n--FML-[NoteBlock]\nOfficia 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.\n--FML-[CodeExample]\n--FML-[PropsTable]\n"
  },
  computed: {
    pureContent() {
      const c = this.preContent;
      const re = new RegExp(`--FML-\\[(\\w+)\\]`, 'g');

      return c.replace(re, ($0, $1) => ``);
    },
    postProcessSpec() {
      return {
        template: `${this.pureContent}`,
        data() {
          return {
            codeexample: {
              template: 'This is the CODEEXAMPLE component
'}, блокнот: {template:'
Это компонент NOTEBLOCK
'}, доступный: {template:' Таблица свойств! '}}}, компоненты: {}};}}});
<script src="https://unpkg.com/vue@latest/dist/vue.js"></script>
<div id="app">
  <component :is="postProcessSpec"></component>
</div>
...