次のようなコンポーネントがあります。
Relation.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
Entry
JSON.parse()
ところで、これを機能させるには、vue.config.js で runtimeCompiler を有効にする必要があります。
module.exports = {
runtimeCompiler: true
}
JSXを使用してオブジェクトを含むコンポーネントを返すことができることは知っていますが、これはrender()関数でのみ許可されているようで、私のようなカスタム関数では許可されていません。
ありがとう!!