不能用过滤器安全地把对象转成 json 字符串并格式化显示,因过滤器在小程序平台被忽略、无法处理循环引用或函数等风险,且 vue 3 已移除 filters;应改用计算属性或工具函数调用 safestringify 并加 try-catch 兜底。

不能用过滤器安全地把对象转成 JSON 字符串并格式化显示——因为过滤器在模板中执行时,无法控制 JSON.stringify 的缩进、循环引用、函数/undefined 值等风险,且小程序平台会忽略 filters 选项。
为什么 {{ obj | toJson }} 在小程序里不显示?
uni-app 的 Vue 2 模式下,微信小程序、支付宝小程序等平台在编译阶段直接丢弃 filters 配置,filters 仅在 H5 端有效;Vue 3 模式则已彻底移除该语法。即使 H5 能跑,{{ obj | toJson }} 也容易因对象含函数、Symbol、undefined 或循环引用而报错。
- 全局注册的
Vue.filter('toJson', ...)在小程序里不会生效,控制台无提示,只渲染为空 - 局部
filters: { toJson() { ... } }同样被忽略,不是 bug,是平台限制 - 哪怕 H5 跑通,
JSON.stringify(obj)对undefined、function、Symbol默认跳过,但开发者常误以为“能转就等于能安全展示”
想在模板里显示格式化 JSON,该怎么做?
用计算属性提前处理,或封装为方法调用,确保可控、可兜底、跨平台一致:
- 在
computed中写:formattedJson() { try { return JSON.stringify(this.obj, null, 2) } catch (e) { return '{ /* invalid */ }' } } - 模板中直接写:
{{ formattedJson }},不走过滤器链 - 若需复用,抽成工具函数:
export function safeStringify(obj, space = 2) { try { return JSON.stringify(obj, (k, v) => typeof v === 'undefined' ? null : v, space) } catch { return '{}' } } - 注意:不要在
v-for里反复调用JSON.stringify,大数据量会卡顿;应提前在data或computed中缓存结果
如果非要“像过滤器一样用”,怎么绕过平台限制?
本质是模拟过滤器调用语法,但底层不用 filters 机制:
- 在
methods里定义:toJson(obj) { return safeStringify(obj) } - 模板中写:
{{ toJson(obj) }}—— 这种写法 H5、App、小程序全部支持 - 避免传入未定义对象:
{{ obj && toJson(obj) }}或用可选链(Vue 3):{{ toJson(obj?.data) }} - 别在
onLoad里直接this.toJson = safeStringify,方法必须声明在methods下才响应式可用
真正容易被忽略的是:JSON 格式化不是“显示需求”,而是“调试辅助”。生产环境不该把整个对象 dump 到界面,应明确提取字段;真要展示结构化数据,优先用 <pre class="brush:php;toolbar:false;"><code></code> 包裹,且必须对 <code>、<code>></code> 做 HTML 转义,否则有 XSS 风险。</code></pre>











