Vue2中如何直接加载SVG用于Leaflet divIcon无需经JS文件导入
Vue2项目Leaflet divIcon直接加载SVG文件方案
你之前用require('./TheCloud.svg')加载失败的核心原因是:Vue CLI默认的webpack配置会把SVG文件交给file-loader处理,返回的是资源访问路径,不是SVG原始源码字符串,把路径字符串直接传给divIcon的html参数,当然无法正常渲染图标。
以下是3种不需要把SVG源码手动写入JS文件的实现方案,都支持直接获取SVG源码用于后续修改:
方案1:配置webpack导入SVG原始字符串(推荐)
这个方案侵入性最低,不需要调整现有文件结构,导入即可拿到SVG源码:
- 先安装raw-loader依赖:
npm install raw-loader --save-dev - 在项目根目录的
vue.config.js中添加webpack规则,支持通过?raw后缀导入文件原始内容:module.exports = { chainWebpack: config => { config.module .rule('raw-svg') .test(/\.svg$/) .resourceQuery(/raw/) .use('raw-loader') .loader('raw-loader') .end() } } - 导入SVG时加上
?raw后缀,直接拿到原始SVG字符串,传入divIcon即可正常渲染:
后续要修改SVG时,直接操作拿到的SVG字符串,或者转成DOM节点修改后再序列化即可。import cloudSvg from './TheCloud.svg?raw' export default { data() { return { cloudSvg } }, methods: { createCloudIcon(size = 32) { return L.divIcon({ html: this.cloudSvg, className: 'my-custom-icons', iconSize: [size, size], iconAnchor: [size/2, size/2] }) } } }
方案2:请求静态目录下的SVG文件
如果不想修改webpack构建配置,可以把SVG文件放到public目录(Vue CLI 3+)或者static目录(Vue CLI 2.x),在组件中通过fetch请求拿到SVG源码:
- 将目标SVG文件移动到项目静态资源目录
- 在组件生命周期中请求SVG资源,拿到源码后再初始化地图标记:
export default { data() { return { cloudSvg: '' } }, async mounted() { // 对应静态目录下的TheCloud.svg访问路径 const resp = await fetch('/TheCloud.svg') this.cloudSvg = await resp.text() // 源码获取完成后,再执行地图初始化、marker添加逻辑 } }
这个方案的缺点是SVG需要放在静态资源目录,会多一次本地资源请求,基本无性能影响。
方案3:SVG组件转HTML字符串
Vue CLI默认支持将SVG作为Vue组件导入,可以把组件渲染后拿到HTML字符串传入divIcon:
- 按Vue默认规则导入SVG组件
- 写一个工具方法将组件渲染为真实DOM,取内部HTML字符串传入divIcon:
import CloudSvgComponent from './TheCloud.svg' export default { methods: { getCloudSvgHtml() { const mountNode = document.createElement('div') const Component = Vue.extend(CloudSvgComponent) new Component().$mount(mountNode) return mountNode.innerHTML }, createCloudIcon(size = 32) { return L.divIcon({ html: this.getCloudSvgHtml(), className: 'my-custom-icons', iconSize: [size, size], iconAnchor: [size/2, size/2] }) } } }
这个方案需要额外做一次组件挂载、取HTML的操作,适合已经在项目中全局使用SVG组件的场景。
避坑提示:不要直接把默认导入的SVG路径、SVG组件对象传给divIcon的html参数,该参数只接收HTML字符串,传入其他类型值都会导致渲染异常。
内容的提问来源于stack exchange,提问作者ericg
相关产品推荐
相关产品推荐

