我正在尝试使用其中的动态信息创建 Google 地图标记。对于该功能,我使用带有 SVG 作为模板的 Vuejs-Component 并添加"text"-Tag。
例子:
<template>
<svg width="40px" height="56px" viewBox="0 0 40 56" version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<text>{{ text }}</text>
</svg>
</template>
<script>
export default {
name: "DynamicGMapMarker",
props: {
text: {
type: String,
required: true
}
}
}
</script>
然后我通过一个辅助函数创建 SVG 并创建一个 base64 数据 url:
import Vue from 'vue'
import DynamicGMapMarker from './DynamicGMapMarker'
const DynamicGMapMarkerConstructor = Vue.extend(DynamicGMapMarker)
export const getDynamicMarkerIcon = (text) => {
const iconComponent = new DynamicGMapMarkerConstructor({
propsData: {
text
}
});
iconComponent.$mount();
const iconDom = iconComponent.$el;
const iconString = new XMLSerializer().serializeToString(iconDom);
return 'data:image/svg+xml;charset=UTF-8;base64,' + btoa(iconString);
}
现在,我可以使用该getDynamicMarkerIcon()
功能了。这适用于vue.js,但不适用于nuxt.js。在 nuxt.js 中,我们需要从 npm 添加一个 XML-Serializer,因为 nuxt 不能使用浏览器的 XMLSerializer。为此,我正在使用teclone/xml-serializer。
现在,问题似乎是 Nuxt 无法创建 DOM,因为 SSR。当我尝试使用此方法时:
<template>
<div id="app">
<GmapMap
:center="center"
:zoom="15"
:options="options"
id="map"
>
<GmapCluster :zoomOnClick="true">
<GmapMarker
:key="index"
v-for="(marker, index) in markers"
:position="marker.coordinates"
:clickable="true"
:draggable="false"
:title="marker.name"
:icon="getMarker(marker)"
/>
</GmapCluster>
</GmapMap>
</div>
</template>
<script>
import GmapCluster from 'vue2-google-maps/dist/components/cluster'
import {getMarkerIcon} from "./MapIconUtil"
export default {
name: 'App',
components: {
GmapCluster
},
methods: {
getMarker(marker) {
return getDynamicMarkerIcon(marker.text);
}
},
data() {
return {
options: {
zoomControl: false,
mapTypeControl: false,
scaleControl: false,
streetViewControl: false,
rotateControl: false,
fullscreenControl: false,
disableDefaultUi: true,
clickableIcons: false
},
center: {
lat: 11,
lng: 11
},
"markers": [
{
coordinates: {
name: "Test",
lat: 11.0001,
lng: 11.0001,
text: "101"
}
}
]
}
}
}
</script>
我收到一个iconComponent.$el
未定义的错误。我无法在 DOM 中安装 SVG。
有没有可能告诉 Nuxt,这个组件应该只在浏览器端运行?
我已经尝试过GmapMarker
使用<client-only>
-Tag。那没有用。我可以使用“虚拟 DOM”之类的东西吗?任何其他想法如何使它工作?