不能用过滤器安全实现全角转半角——因uni-app过滤器仅h5端执行,小程序/app端不生效,且存在空值、emoji、编码范围遗漏等边界问题;应改用纯函数封装+显式调用。

不能用过滤器安全实现全角转半角——因为 uni-app 的过滤器在小程序和 App 端根本不会执行,H5 端虽能跑但逻辑不可跨端,且字符串边界处理极易出错。
为什么 Vue.filter 不适合全角转半角
全角字符(如 、A、1、,)转半角( 、A、1、,)需逐字符映射,涉及 Unicode 码点判断。而 uni-app 的过滤器机制存在三重硬限制:
-
Vue.filter注册的函数仅在 H5 端被 template 编译器识别,微信/支付宝/字节等小程序平台直接跳过|语法,模板里写{{ text | full2half }}在真机上原样输出,不报错也不执行 - 即使只跑 H5,
toLowerCase()类简单方法能兜底,但全角转半角必须查表或正则,一旦传入null、undefined或含 emoji 的字符串,String.prototype.replace可能静默失败或返回NaN - 全角空格
\u3000是否转为 ASCII 空格是业务决策,不是技术默认行为——过滤器里硬编码会破坏语义(如「姓名 张三」缩进丢失),但过滤器又无法接收配置参数
真正能用的替代方案:封装纯函数 + 显式调用
把转换逻辑从模板层彻底移出,统一用工具函数控制,所有端表现一致:
- 在
@/utils/transform.js中定义:export const full2half = (str) => { if (typeof str !== 'string') return '' return str.replace(/[\uFF01-\uFF5E]/g, (char) => String.fromCharCode(char.charCodeAt(0) - 0xfee0) ).replace(/\u3000/g, ' ') } - 页面中导入并使用:
import { full2half } from '@/utils/transform' // 模板中不写 |,而是: <view>{{ full2half(item.title) }}</view> // 或配合 computed 缓存: const displayTitle = computed(() => full2half(props.item.title)) - 注意:该函数未处理全角数字/字母外的符号(如 → 空格已处理,但「~」→「~」需额外加映射),若业务要求严格,应复用 Python 那套
FULL2HALF_TABLE思路,用String.fromCodePoint()构建完整映射表
别踩的坑:模板里强行用过滤器的典型翻车点
即使你坚持在 main.js 里写了 Vue.filter('full2half', ...),以下情况仍会失效:
-
{{ item?.name | full2half }}—— 可选链?.在 Vue 2 模板中不被支持,编译直接报错Invalid expression -
{{ (item.name || '') | full2half }}—— 括号在 Vue 2 过滤器链中非法,|只接受单个表达式,括号触发语法错误 - 传入值是响应式对象深层属性(如
item.info.text),但item.info初始为undefined,过滤器内部str.replace会因undefined.replace报TypeError,且错误发生在渲染阶段,白屏难定位 - 在
v-for中高频调用,每次 diff 都执行一遍正则,无缓存,低端安卓机卡顿明显
最易被忽略的是:全角符号映射表是否覆盖业务实际输入。比如用户粘贴的「,」(中文逗号)和「、」(顿号)不在 \uFF01-\uFF5E 范围内,需要单独扩展正则或查表;而这些细节,只有在 JS 层主动调用函数时才能可控补充。











