如何创建一个动态 vue 组件,该组件具有一个计算模板,该模板包含另一个具有对象属性的组件而不将其作为字符串传递
how to create a dynamic vue component that has a computed template containing another component with Object properties without passing it as string
我有这样一个组件:
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
组件具有类型为 String
的 属性 entry
,但我必须 JSON.stringify()
[中的条目对象=19=] 端,然后在 Entry
组件中,我必须 JSON.parse()
字符串才能取回真实对象。
我怎样才能完成上述工作,以便将对象直接传递给动态模板,从而始终避免序列化和反序列化。
顺便说一句,要使它运行,需要在 vue.config.js:
中启用 runtimeCompiler
module.exports = {
runtimeCompiler: true
}
我知道我可以将 JSX 用于 return 带有对象的组件,但这似乎只在 render() 函数中允许,而不是像我这样的自定义函数。
谢谢!!
我仍然可以通过使用 JSON.stringify 来做我想做的事,但将条目作为对象传递 :entry
wierd.service.js
export default {
entryToHtml(entry) {
return `<entry :entry='${JSON.stringify(entry)}'></entry>`;
}
}
Entry.vue
<template>
<div>{{entry.name}}</div>
</template>
<script>
export default {
name: 'Entry',
props: {
entry: Object
}
}
</script>
我有这样一个组件:
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
组件具有类型为 String
的 属性 entry
,但我必须 JSON.stringify()
[中的条目对象=19=] 端,然后在 Entry
组件中,我必须 JSON.parse()
字符串才能取回真实对象。
我怎样才能完成上述工作,以便将对象直接传递给动态模板,从而始终避免序列化和反序列化。
顺便说一句,要使它运行,需要在 vue.config.js:
中启用 runtimeCompilermodule.exports = {
runtimeCompiler: true
}
我知道我可以将 JSX 用于 return 带有对象的组件,但这似乎只在 render() 函数中允许,而不是像我这样的自定义函数。
谢谢!!
我仍然可以通过使用 JSON.stringify 来做我想做的事,但将条目作为对象传递 :entry
wierd.service.js
export default {
entryToHtml(entry) {
return `<entry :entry='${JSON.stringify(entry)}'></entry>`;
}
}
Entry.vue
<template>
<div>{{entry.name}}</div>
</template>
<script>
export default {
name: 'Entry',
props: {
entry: Object
}
}
</script>