uni-app中svg跨端渲染的正确方案是:内联svg字符串+v-html(仅h5)或转为字体图标(全平台推荐)。小程序不支持加载svg,标签会被忽略,v-html在小程序中被过滤;字体图标兼容性最好,内联svg适用于h5动态场景,canvas渲染仅作最后兜底。

uni-app 中直接用 <image></image> 标签加载 SVG 文件会失败
因为绝大多数小程序平台(微信、支付宝、字节)不支持 <image></image> 直接渲染 SVG,H5 环境虽部分支持,但行为不一致(比如微信小程序里显示为空白,控制台无报错)。这不是路径写错或路径没配对,是底层限制。
真正能稳定跨端渲染 SVG 的方式只有两种:内联 SVG 或转为字体图标。前者适合单图、动态修改场景;后者适合图标库、多图标复用。
- 不要把 SVG 放进
static目录后用<image src="/static/icon.svg"></image>—— 小程序里必然不显示 - 不要在
template里直接写<svg>...</svg>并期望它被自动解析 —— uni-app 不做 HTML 解析,<svg></svg>标签会被当作文本节点忽略 - 如果用
v-html渲染 SVG 字符串,H5 可行,但小程序平台会过滤掉<svg></svg>及其子标签(安全策略)
推荐方案:用 require 内联 SVG 字符串 + v-html(仅限 H5)
适用于 H5 端为主、少量 SVG 图标、需动态着色或尺寸控制的场景。本质是把 SVG 当作字符串读入,再由浏览器原生渲染。
注意:此法在微信/支付宝等小程序中无效,编译时不会报错,但运行时空白。
// 在 .vue 文件的 script 中
export default {
data() {
return {
svgContent: ''
}
},
onLoad() {
// ✅ 正确写法:用 require 读取 SVG 文件内容(必须是本地文件,不能是网络地址)
this.svgContent = require('@/static/logo.svg')
}
}
模板中使用:
<div v-html="svgContent" class="svg-wrapper"></div>
补充要点:
-
require路径必须是相对路径或以@/开头的别名路径,不能是变量拼接(否则 webpack 无法静态分析) - SVG 文件建议手动精简:删掉
<?xml ...?>、注释、多余命名空间(如xmlns:xlink),只保留<svg>...</svg>结构 - H5 下可加
class控制宽高,但 SVG 内部的width/height属性优先级更高,建议统一用viewBox+ CSS 控制缩放
真正跨端方案:转成字体图标(推荐用 iconfont + uni-icon)
这是目前最成熟、兼容性最好的方案。uni-app 官方 uni-icon 组件底层就是基于字体图标,天然支持所有平台。
操作流程简单:去 iconfont.cn 创建项目 → 上传 SVG → 下载字体包 → 替换 static/fonts/ 下对应文件 → 在 uni.scss 中配置 @font-face → 使用 <uni-icon></uni-icon> 或自定义 class。
关键配置示例(static/fonts/iconfont.css):
@font-face {
font-family: "iconfont";
src: url('iconfont.woff2') format('woff2'),
url('iconfont.woff') format('woff'),
url('iconfont.ttf') format('truetype');
}
然后在 uni.scss 里引入:
@import '@/static/fonts/iconfont.css';
使用时:
<uni-icon type="" size="24"></uni-icon><span class="iconfont"></span>
注意事项:
- 确保字体文件放在
static/fonts/下(不能放assets/,否则 H5 和小程序资源路径处理逻辑不同) - Unicode 编码要和 iconfont 后台生成的一致,复制时注意别带空格或不可见字符
- 字体图标默认不支持渐变、滤镜等 SVG 特性,如有复杂动效需求,得回归内联 SVG + H5 专用分支
小程序平台特殊处理:用 canvas 渲染 SVG(极少数场景)
仅当必须在小程序里渲染动态 SVG(比如图表、简易动画),且无法接受字体图标限制时考虑。本质是用第三方库(如 canvg)将 SVG 字符串绘制成 canvas 图片。
但代价明显:体积大(canvg gzip 后仍 >100KB)、性能差(每次重绘都要解析+绘制)、不支持交互事件(canvas 是位图)。
实操建议:
- 先确认是否真需要 SVG 动态能力 —— 多数图标类需求,字体图标 + CSS 动画已足够
- 若必须用,只在小程序平台按需引入:
const canvg = uni.getSystemInfoSync().platform === 'devtools' ? null : require('canvg') - 避免在
onLoad中同步执行耗时渲染,应加 loading 状态,并用setTimeout延迟触发,防止卡顿
跨端 SVG 最难的不是“怎么放进去”,而是“在哪能真正起作用”。字体图标是默认解,内联 SVG 是 H5 加餐,canvas 是最后兜底——选错路径,后面全是兼容性补丁。











