AI取名大师 | uni-app 微信小程序显示不了 SVG 组件?试试换一种实现方式

95 阅读3分钟

关于 AI 取名大师

借助豆包通义千问DeepSeek 等 AI 大模型,为您的宝宝、宠物、店铺、网名、笔名、项目、产品、服务、文章等取一个专业、有意义的名字😄。


开源地址:👉GitCode(国内友好)👈、👉GitHub👈 技术组合:Bun.jsElysia.jsuni-app 体验地址:AI取名大师(H5版)、小程序搜索取名大师


特别注明:本系列文章仅为实战经验分享,并记录开发过程中碰到的问题😄,如有不足之处欢迎随时留言提出。


📣 问题描述

AI取名大师中不同取名模块的图标、颜色可以在后台配置,所以前端用的是SVG格式,每个图标做成一个 vue 组件。在 H5 下完全正常,但是编译为微信小程序后,就无法正常显示😔(如下图所示)。 代码目录下的 svg 图标组件: 经过 uni-app 编译成微信小程序的格式: 在开发者工具下查看组件的细节,发现其内容是空的,因为小程序无法正常识别 <svg /> 标签😂。

🧑‍💻 解决方案

SVG 简介

SVG(Scalable Vector Graphics,可缩放矢量图形)是基于 XML 语法的矢量图形格式,核心优势是无限缩放不失真,且体积小、可编辑。

跟位图(JPG/PNG)的区别

对比项SVG(矢量图)位图(JPG/PNG)
图像本质由路径、线条、形状、文本等数学公式描述由像素点(Pixel)组成
放大清晰度无限放大不失真放大后会模糊、出现锯齿
文件大小图形简单时非常小;复杂图形(如插画)可能变大与图片分辨率有关,通常比简单 SVG 大
适用场景图标、Logo、可缩放 UI、数据可视化、动画摄影图片、纹理、背景、复杂色彩渐变
可编辑性可用代码(XML)编辑;支持动态修改颜色、大小不易通过代码修改;多依赖图像编辑软件
渲染性能小图标性能优;超复杂 SVG 渲染性能可能下降渲染相对稳定;高分辨率需要更多内存
透明度支持原生支持透明JPG 不支持透明;PNG 支持
动画支持支持 CSS/JS/SVG animation 动画JPG/PNG 本身不支持动画(GIF 例外)
兼容性广泛支持(但部分小程序平台有限制)兼容性强,无平台限制
加载方式代码内嵌、组件引入、外链均可图片 URL 加载为静态资源

跨平台下 SVG 支持情况

平台SVG 支持
Web(H5)✔ 完全支持
APP(WebView)✔ 基本支持
微信小程序几乎不支持 <svg> 标签
Uni-app H5✔ 支持
Uni-app 小程序❌ 需转 PNG/Base64/iconfont

自定义组件

定义通用的函数

const toBase64 = text=>{
    // #ifndef H5
    return uni.arrayBufferToBase64(new TextEncoder().encode(text))
    // #endif
    // #ifdef H5
    return btoa(text)
    // #endif
}

export const SVGProps = {
    size: {type:Number, default: 48},
    fill: {type:String, default:"#3D3D3D"},
    clazz: {type:String, default:""}
}

export const buildSVGView = (size, svg)=>({
    width: `${size}px`,
    height: `${size}px`,
    backgroundImage: `url('data:image/svg+xml;base64,${toBase64(unescape(encodeURIComponent(svg)))}')`,
    backgroundSize: 'contain'
})

再定义组件

<template>
    <view :class="clazz" :style />
</template>

<script setup>
    import { SVGProps, buildSVGView } from "."
    const props = defineProps(SVGProps)

    const style = computed(()=>{
        let { size, fill } = props
        let svg = `<svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 1024 1024"><path fill='${fill}' d="M512 192.555c-163.968 0-301.141 113.664-335.659 265.728a81.5 81.5 0 0 0-28.586-5.12 80.555 80.555 0 0 0-81.024 80.17c0 44.288 36.266 80.214 80.938 80.214a81.3 81.3 0 0 0 28.587-5.163c34.56 152.064 171.733 265.728 335.701 265.728S813.1 760.448 847.616 608.384c8.917 3.328 18.56 5.12 28.587 5.12a80.555 80.555 0 0 0 80.981-80.17c0-44.289-36.267-80.214-80.939-80.214a81.5 81.5 0 0 0-28.586 5.163c-34.56-152.064-171.734-265.728-335.702-265.728zm512 340.778c0 72.96-55.296 133.803-127.659 143.403C837.12 831.488 685.781 938.666 512 938.666s-325.12-107.178-384.341-261.93C55.296 667.136 0 606.336 0 533.333c0-72.96 55.296-133.802 127.659-143.402C186.88 235.179 338.219 128 512 128s325.12 107.179 384.341 261.93c72.363 9.6 127.659 70.4 127.659 143.403m-636.075 68.694a29.397 29.397 0 0 1 25.814 32.213 91 91 0 0 0-.342 7.85c0 51.798 44.075 94.123 98.603 94.123s98.56-42.325 98.56-94.122a105 105 0 0 0-.256-7.339 29.355 29.355 0 0 1 26.027-32 28.93 28.93 0 0 1 31.018 27.093c.299 4.054.47 8.107.47 12.246 0 84.906-69.846 153.472-155.819 153.472s-155.819-68.523-155.819-153.43c0-4.394.171-8.789.555-13.184a28.93 28.93 0 0 1 31.19-26.88zM546.39 368.896a213 213 0 0 1 22.016-49.365c2.56-4.438 3.926-6.998 5.291-9.942 3.413-7.296 6.4-16.213 9.515-28.97a31.061 31.061 0 0 1 60.288 14.634 213.3 213.3 0 0 1-13.526 40.278c-2.133 4.65-4.224 8.533-7.594 14.421a155.7 155.7 0 0 0-16.896 37.76c-1.195 3.755-2.475 8.533-3.84 14.08-1.75 7.424-5.419 25.173-5.675 25.856-5.29 14.293-17.365 22.4-32.683 23.168-1.408.043-4.053 0-8.874-.085h-1.28a376 376 0 0 0-6.699-.171c-78.336 0-176.597-88.96-176.597-162.603 0-16.981 13.866-30.805 31.061-30.805s31.019 13.824 31.019 30.805c0 37.334 64.298 95.744 109.013 100.694 1.621-6.827 3.499-13.654 5.461-19.755M339.115 551.253c-30.72 0-55.68-24.064-55.68-53.76 0-29.738 24.917-53.845 55.68-53.845 30.72 0 55.637 24.107 55.637 53.803 0 29.738-24.917 53.802-55.637 53.802m359.381 0c-30.72 0-55.68-24.064-55.68-53.76 0-29.738 24.917-53.845 55.68-53.845 30.72 0 55.637 24.107 55.637 53.803 0 29.738-24.917 53.802-55.637 53.802"/></svg>`

        return buildSVGView(size, svg)
    })
</script>

注意

  1. <svg />标签的 xmlns="http://www.w3.org/2000/svg"不能删除(否则不能正常显示)
  2. url必须使用 unescape 函数转义

📖 参考文档