小程序中background-image仅支持/static/绝对路径、线上URL或base64;需用uni.getFileSystemManager().readFile读取/static下图片转base64,H5与小程序须条件编译,且必须通过:style绑定内联样式。

小程序端 background-image 路径报错:必须用绝对路径且不能是本地相对路径
uni-app 在小程序平台(尤其是微信)里,background-image 的 URL 不能写 ./assets/bg.png 这类相对路径,编译后会变成无效地址或直接 404。这是因为小程序的 WXML/CSS 不支持运行时解析相对路径,且不走 webpack 的资源处理流程。
真正能生效的只有三类路径:
-
/static/bg.png(以/static开头的绝对路径,文件必须放在项目根目录的static文件夹下) -
https://xxx.com/bg.png(线上 CDN 地址) -
data:image/png;base64,...(base64 字符串,绕过路径限制)
注意:/assets 目录在小程序中不会被自动拷贝到构建产物里,只有 /static 是 uni-app 明确约定的静态资源目录,会被原样复制到小程序根目录。
uni-app 中图片转 base64:别用 require(),改用 uni.getFileSystemManager().readFile()
很多人习惯在 H5 端用 require('./xxx.png') 得到 base64,但这在小程序端会报错 —— require is not defined。因为小程序不支持 CommonJS 动态引入,且 require 只在编译期起作用,无法用于运行时路径拼接。
正确做法是用 uni 提供的跨端 API 读取本地文件(仅限 /static 下的图):
const fs = uni.getFileSystemManager();
fs.readFile({
filePath: '/static/bg.png',
encoding: 'base64',
success: (res) => {
this.bgStyle = `background-image: url(data:image/png;base64,${res.data});`;
}
});
关键点:
- 路径必须是
/static/xxx开头的绝对路径 - 只支持同步读取(
readFileSync)或异步回调,不能 await(除非封装 Promise) - 微信小程序要求图片小于 10MB;支付宝等平台可能更严,超限会报
fail file size too large
uni-app 条件编译写法:H5 用 require,小程序用 readFile
同一张背景图,在 H5 可以直接 require 编译成 base64,小程序却必须运行时读取 —— 这时候靠条件编译最稳妥,而不是试图写“通用”逻辑。
示例(Vue 单文件组件 setup 中):
// #ifdef H5
const bgBase64 = require('@/static/bg.png');
this.bgStyle = `background-image: url(${bgBase64});`;
// #endif
// #ifdef MP-WEIXIN || MP-ALIPAY
const fs = uni.getFileSystemManager();
fs.readFile({
filePath: '/static/bg.png',
encoding: 'base64',
success: (res) => {
this.bgStyle = `background-image: url(data:image/png;base64,${res.data});`;
}
});
// #endif
注意:
-
#ifdef块内不能混用响应式赋值(比如this.xxx = ...)和组合式 API 的ref/reactive,需按实际语法调整 - 不要在
onLoad之前就调用readFile,否则this可能未就绪;建议放在onReady或显式初始化函数中 - 如果图是用户上传的临时路径(
tempFilePath),readFile也支持,但要注意有效期(通常 1 天)
容易被忽略的坑:CSS 里的 url() 不会触发条件编译,也不能写变量
很多人想直接在样式里写 background-image: url({{bgUrl}}); 或用 :style 绑定,但这是错的——CSS 本身不解析 Vue 模板语法,url() 里的内容必须是字符串字面量或合法 CSS URL。
所以以下写法全都不行:
-
background-image: url({{base64Str}});(CSS 不认识双大括号) -
background-image: url(require('./x.png'));(小程序报错,H5 也只在编译期有效,无法动态切换) - 把 base64 字符串拼进 class 名再用 CSS 定义(冗余、不可维护)
唯一可靠方式是用 :style 绑定一个内联 style 对象,且确保值是完整字符串::style="{ backgroundImage: `url(data:image/png;base64,${base64})` }"。记住:base64 前缀、格式、分号,一个都不能少,漏了就变空白背景。


















