Как создать компонент Dynami c vue, который имеет вычисляемый шаблон, содержащий другой компонент со свойствами объекта, не передавая его в виде строки - PullRequest
0 голосов
/ 06 января 2020

У меня есть такой компонент:

Отношение. vue

<template>
    <div :is="dynamicRelation"></div>
</template>

<script>
  import Entry from '@/components/Entry';
  import weirdService from '@/services/weird.service';
  export default { 
      name: 'Relation',
      data() {
         return {
             entry1: { type: 'entity', value: 'foo', entity: {id: 4}},
             entry2: { type: 'entity', value: 'bar', entity: {id: 5}},
             innerText: '@1 wut @2',
         } 
      },
      computed: {
          dynamicRelation() {
              return {
                  template: `<div>${this.innerText
                        .replace('@1', weirdService.entryToHtml(this.entry1))
                        .replace('@2', weirdService.entryToHtml(this.entry2))}</div>`,
                  name: 'DynamicRelation',
                  components: { Entry }
              };
          }
      }
  }
</script>

wierd.service. js

export default {
   entryToHtml(entry) {
       [some logic]
       return `<entry entry='${JSON.stringify(entry)}'></entry>`;
       // unfortunately I cannot return JSX here: <entry entry={entry}></entry>; 
       // I get 'TypeError: h is not a function'
       // unless there is a way to convert JSX to a pure html string on the fly
    }
}

Entry. vue

<template>
    <div>{{objEntry.name}}</div>
</template>

<script>
  export default { 
      name: 'Entry',
      props: {
          entry: String // I need this to be Object
      },
      computed: {
          objEntry() {
              return JSON.parse(this.entry);
          }
       }
   }
</script>

Свойство innerText решает, как будут отображаться компоненты, и его можно все время менять, имея его @ слоты в любом положении. В этом примере результат:

<div>
   <div>foo</div> 
   wut 
   <div>bar</div>
</div>

Это работает, так как Entry компонент имеет свойство entry, которое имеет тип String, но мне нужно JSON.stringify() объект ввода в weirdService side, а затем в Entry компоненте мне нужно JSON.parse() строку, чтобы вернуть реальный объект. Как сделать так, чтобы вышесказанное работало так, чтобы я передавал объект непосредственно в динамический шаблон c, чтобы я все время избегал сериализации и десериализации.

Кстати, чтобы это работало, необходимо включить runtimeCompiler в vue .config. js:

module.exports = { 
    runtimeCompiler: true
}

Я знаю, что могу использовать JSX для возврата компонентов с объектами в них, но это разрешено только в функции render (), а не в пользовательских, таких как моя.

Спасибо !!

1 Ответ

0 голосов
/ 06 января 2020

Я смог сделать то, что хотел, используя JSON .stringify, но передать запись как объект :entry

wierd.service. js

export default {
   entryToHtml(entry) {
       return `<entry :entry='${JSON.stringify(entry)}'></entry>`;
    }
}

Вступление. vue

<template>
    <div>{{entry.name}}</div>
</template>

<script>
  export default { 
      name: 'Entry',
      props: {
          entry: Object
      }
   }
</script>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...