不能用过滤器安全实现考试成绩转等级,因小程序端不执行自定义filter、vue 3已移除该语法、h5端缺乏类型防护和边界兜底,易致空白或报错。

不能用过滤器安全实现考试成绩转等级——uni-app 小程序端不执行自定义 filter,Vue 3 模式下已移除该语法,H5 端即使能跑也缺乏类型防护和边界兜底,容易渲染空白或报错。
为什么 {{ score | gradeLevel }} 在真机上不生效
uni-app 的小程序平台(微信/支付宝/字节等)根本不会解析或执行 Vue.filter() 注册的函数,模板里的 | 语法被直接忽略;即使项目配置为 Vue 2 模式(vueVersion: "2"),App 和小程序端仍无法保证 filter 调用上下文存在。常见现象是:H5 正常显示“优”,真机却始终为空白或原数字。
- 过滤器注册只在
main.js生效,但小程序编译时会剥离这部分逻辑 -
{{ score | gradeLevel }}中若score是null、undefined或字符串"--",filter 函数内部未判空就会直接返回undefined,导致视图异常 - 不同端对浮点数精度、字符串比较、
parseInt行为不一致,比如"89.9"在 iOS 可能被截断为89,Android 保留89.9
gradeLevel 过滤器怎么写才不容易崩
如果坚持在 H5 环境临时使用(非生产推荐),必须满足三个条件:全局注册、强类型输入、全覆盖映射。不要依赖 this 或异步逻辑。
- 注册位置必须在
main.js中new Vue()之前,且仅限 Vue 2 模式 - 函数体要主动处理非数字输入:
const num = Number(value),再判断isNaN(num),返回兜底值如"缺考" - 分数段建议用闭区间明确划分,避免
>= 90和之间留缝隙,例如:<code>num >= 90 ? '优' : num >= 80 ? '良' : num >= 70 ? '中' : num >= 60 ? '差' : '不及格' - 别加参数如
{{ score | gradeLevel('chinese') }}——Vue 2 不支持带参 filter 的模板写法,会编译报错
真正跨端稳定的替代方案
把等级映射逻辑从模板层彻底移出,封装成纯函数,在 data、computed 或 setup 中调用。这样三端行为一致,也方便单元测试。
- 在
utils/grade.js中导出:export function scoreToGrade(score, fallback = "未知") { const n = Number(score); return isNaN(n) ? fallback : n >= 90 ? "优" : n >= 80 ? "良" : n >= 70 ? "中" : n >= 60 ? "差" : "不及格"; } - 页面中直接使用:
{{ scoreToGrade(item.score) }}(需在methods或setup中引入并返回) - 若需响应式更新(如搜索后重算),放在
computed里:gradeText() { return scoreToGrade(this.currentScore); } - 批量处理列表时,不要在
v-for模板里反复调用函数,改用computed预计算整个数组:gradedList() { return this.rawList.map(i => ({ ...i, grade: scoreToGrade(i.score) })); }
最容易被忽略的细节
后端返回的 score 字段可能是字符串 "85"、"缺考"、null,甚至空对象 {},而前端硬写 score >= 90 会导致 NaN >= 90 === false,最终落到兜底分支。这不是 filter 写得不够好,而是原始数据质量不可控——必须在数据进组件前就清洗,或在工具函数里做防御性转换。别指望模板语法能兜住业务数据的混乱。










