0

我有一个这样的组件:

关系.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>

奇怪的服务.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
    }
}

入口.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()在 side 中输入对象weirdService,然后在Entry组件中我必须JSON.parse()使用字符串才能取回真实对象。我怎样才能使上述工作,以便我将一个对象直接传递给一个动态模板,这样我就可以一直避免序列化和反序列化。

顺便说一句,要使其工作 runtimeCompiler 需要在 vue.config.js 中启用:

module.exports = { 
    runtimeCompiler: true
}

我知道我可以使用 JSX 返回包含对象的组件,但这仅在 render() 函数中允许,而不是像我这样的自定义函数。

谢谢!!

4

1 回答 1

0

我仍然可以通过使用 JSON.stringify 来做我想做的事,但是将条目作为对象传递:entry

奇怪的服务.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>
于 2020-01-05T23:16:17.977 回答