Rendering Vue 3 component into HTML string(将Vue 3组件呈现为HTML字符串)
问题描述
我正在做一个vue.js项目(版本3)。我遇到了这样一种情况:我想要将呈现的组件的HTML视图用于当前组件的方法。
我在Vue项目中创建了以下SVG组件。
CircleWithTextSvg.vue
<template>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" style="shape-rendering:geometricPrecision; text-rendering:geometricPrecision; image-rendering:optimizeQuality; fill-rule:evenodd; clip-rule:evenodd" width="20" height="20">
<g id="UrTavla">
<circle cx="10" cy="10" r="10" stroke="gray" stroke-width="1" :fill="fill" />
<text x="50%" y="50%" text-anchor="middle" stroke="black" stroke-width="1px" dy=".3em">{{text}}</text>
</g>
</svg>
</template>
<script>
export default {
props: {
text: {
type: String,
default: "1"
},
fill: {
type: String,
default: "white"
}
}
}
</script>
该组件基本上呈现了一个内部带有文本的圆形。 如果我在主组件的模板部分使用此组件,如下所示,则它工作得很好(显然)
MainComponent.vue
<template>
<circle-with-text-svg />
</template>
但我想将此SVG组件呈现的输出作为选项发送给第三方。
实际用例:-实际上,我创建了这个单独的组件,以便在我的传单地图上显示为一个标记。问题是现在我想在MainComponent的方法中使用这个SVG组件,这样我就可以将它用作L.divIcon的一个选项
当我尝试以下操作时
export default {
methods: {
generateMap(element) {
// ...
let icon = L.divIcon({
html: <circle-with-text-svg
fill="'#D3D5FF'"
text="1" />,
iconSize: [10, 10]
});
// ...
}
}
}
然后给出错误
当前未启用对实验语法‘JSX’的支持
在反应中,我们可以简单地正常使用另一个组件的模板中的组件。但我们如何在vue.js中实现这一点
通过查看该错误,似乎未启用JSX实验版。
有人能告诉我如何实现这一点吗?
推荐答案
好,所以我在评论中推荐了问题How to get the compiled html content of a component in vuejs的答案,它实际上是为Vue 2实现的
我很好奇这在Vue 3中是否有效,您可以看到下面的结果。以下是需要更改的内容:
- 明显的变化是将
new Vue
替换为createApp
,而使用传递给render()
的global h() - 在Vue 2中,可以不带参数调用Vue主实例的
$mount()
函数。这是因为Vue在内存中创建了要挂载到的DOM元素。在Vue 3中不是这种情况-您需要自己提供元素 - 在我的示例中没有使用的一个重大更改但对某些用例非常重要,那就是在Vue 3中,使用
app.component()
在主应用程序实例中注册为全局的组件无法在用于呈现HTML的tempApp
中访问。所有正在使用的组件都必须在相应的实例中注册-请参阅migration guide
// We use component options object with string template
// In the proper Vue app (with Webpack and Vue SFC) this whole block can be replaced with "import CircleWithTextSvg from CircleWithTextSvg.vue"
const CircleWithTextSvg = {
name: 'CircleWithTextSvg',
props: {
text: {
type: String,
default: "1"
},
fill: {
type: String,
default: "white"
}
},
template: `
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" style="shape-rendering:geometricPrecision; text-rendering:geometricPrecision; image-rendering:optimizeQuality; fill-rule:evenodd; clip-rule:evenodd" width="20" height="20">
<g id="UrTavla">
<circle cx="10" cy="10" r="10" stroke="gray" stroke-width="1" :fill="fill" />
<text x="50%" y="50%" text-anchor="middle" stroke="black" stroke-width="1px" dy=".3em">{{text}}</text>
</g>
</svg>
`
}
const app = Vue.createApp({
mounted() {
console.log(this.getIconHtml('Hello!'))
},
methods: {
getIconHtml(text, type) {
const tempApp = Vue.createApp({
render() {
return Vue.h(CircleWithTextSvg, {
text,
type
})
}
})
// in Vue 3 we need real element to mount to unlike in Vue 2 where mount() could be called without argument...
const el = document.createElement('div');
const mountedApp = tempApp.mount(el)
return mountedApp.$el.outerHTML
}
}
})
app.mount('#app')
<script src="https://unpkg.com/vue@3.1.4/dist/vue.global.js"></script>
<div id='app'>
</div>
import
不可用的浏览器中运行。为此,我们使用Vue全局构建和访问Vue全局API,例如使用Vue.createApp
或Vue.h
。在常规Vue应用程序中,您需要将这些函数导入为import { createApp, h } from 'Vue'
注2:可以说,如果与单张组件一起使用的HTML片段像您的CircleWithTextSvg
组件一样简单,那么将它们定义为template literals将不是Vue组件,而是template literals
这篇关于将Vue 3组件呈现为HTML字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:将Vue 3组件呈现为HTML字符串


基础教程推荐
- 响应更改 div 大小保持纵横比 2022-01-01
- 有没有办法使用OpenLayers更改OpenStreetMap中某些要素 2022-09-06
- 动态更新多个选择框 2022-01-01
- 悬停时滑动输入并停留几秒钟 2022-01-01
- 当用户滚动离开时如何暂停 youtube 嵌入 2022-01-01
- 在 JS 中获取客户端时区(不是 GMT 偏移量) 2022-01-01
- Karma-Jasmine:如何正确监视 Modal? 2022-01-01
- 角度Apollo设置WatchQuery结果为可用变量 2022-01-01
- 在for循环中使用setTimeout 2022-01-01
- 我什么时候应该在导入时使用方括号 2022-01-01