wxml 模板审查 · 2026-10-09 15:10

这是审查里标「🔴 完全未查」的三块之一。
查出 11 处死绑定,其中 2 处会展示编造文案给客人。

一、结论

项结论
wxml 文件64 个 / 2,951 行
死绑定(ts 从未赋值)🔴 11 处真死代码 + 5 处无害
🔴 会展示编造文案的2 处(key-route 的标题与副标题)
其余永久不渲染的死块,白占体积 + 误导后续维护

二、怎么查的(可复核,含自证)

对每个 X.wxml + X.ts 配对:

  1. 取 wxml 里 {{field}} 的主字段
  2. 剔除 wx:for-item / wx:for-index 声明的别名(否则 e/tk_0 全是假阳性)
  3. 在同名 .ts 里 \bfield\b 全文搜索 —— 零命中 = 死绑定

⚠️ 第一版我犯的错:没剔除循环别名 ⇒ 报出 26 个「未声明」,

其中 e/tk_0/a/c 全是 wx:for-item="e" 这类别名。

发现方式:去查一条 item-detail 时发现 wxml 明明有 wx:for-item="e"。

⇒ 加上别名剔除后才是上表的 16 处。


三、🔴 会展示编造文案的 2 处(最该改)

components/home/key-route/key-route.wxml:4-5

<view class="section-title html-h2">{{routeTitle || '神山衣领 · 转山钥匙'}}</view>
<view class="section-copy html-p">{{routeSub || '转山之前,先到神山衣领。转山之后,回到芝达布日。'}}</view>

🔴 证据:key-route.ts 里 routeTitle / routeSub 零命中(0 处)。

🔴 后果:routeTitle 恒为空 ⇒ 必然走兜底 ⇒

客人每次看到「神山衣领 · 转山钥匙」和那段文案,而这些从未被任何数据驱动过。

⚠️ 与今晚已修的「阿里故事」是同一类问题,但更隐蔽:

「阿里故事」是过期值,这个是从没存在过的值。

建议:要么真给这两个字段赋上值(数据里取),要么删掉兜底、改为空态。

不能保留一段「永远显示的固定文案」 —— 它看起来像有内容,实际是死的。


四、🔴 永久不渲染的死块(8 处)

根因:详情页改成 renderModules 驱动后,旧模板没删

item-detail.ts / product-detail.ts 已改成模块化渲染:

renderModules: [] as any[], // 通用模块渲染 VM(按 tpl 动态分发)
<block wx:for="{{renderModules}}" wx:key="id">   <!-- L134,新路径 -->

但 wxml 里还留着旧的直引用块:

文件死字段守卫结果
item-detail.wxmltext(12 处引用)wx:if="{{text}}"恒空 ⇒ 永不渲染
item-detail.wxmlimageswx:if="{{images.length}}"⚠️ .length 也会抛错
item-detail.wxmlentrieswx:for="{{entries}}"恒空
product-detail.wxml同上 3 个 + videoUrlwx:if="{{videoUrl}}"恒空
hotel-booking.wxmlsubtitlewx:if="{{subtitle}}"恒空
sel-header.wxmlcfg.planTitle / cfg.planDesc`{{cfg.planTitle \\'…'}}`⚠️ cfg 本身不存在 ⇒ cfg.planTitle 报错 ⇒ 走兜底,显示编造文案
key-route.wxmlrouteTitle / routeSub`\\'…'`恒空 ⇒ 显示编造文案

🔴 两个值得单独说的:

① sel-header 的 cfg 连对象都不存在

<view class="pe-title html-span">{{cfg.planTitle || '不确定走几天?先做个规划'}}</view>

sel-header.ts 的 Component({ data: {...} }) 里没有 properties,

data 里也没有 cfg ⇒ {{cfg.planTitle}} 求值 undefined.planTitle

在微信小程序里会抛错 ⇒ 落入兜底 ⇒ 客人看到「不确定走几天?先做个规划」。

② images.length 的隐患

<view class="card motion-reveal" wx:if="{{images.length}}">

若 images 是 undefined,.length 会抛 TypeError(微信的容错会让整块消失,但仍是隐患)。


五、🟡 无害的 5 处

originY 出现在 orders / agreement / feedback / passport / journey 五处:

style="--mo-origin-y:{{originY||'100%'}}"

🔴 ts 里没有 originY,但有 || '100%' 兜底 ⇒ 结果正确(默认位置)。

保留即可,不属于缺陷。


六、修改建议

#改动理由风险
1key-route:给 routeTitle/routeSub 真实赋值,或删掉兜底改空态🔴 客人看到的是从未存在过的文案低
2sel-header:补 properties: { cfg: Object } 或删掉 cfg 引用🔴 同上,且属性求值会抛错低
3删 item-detail / product-detail 里 6 处旧块改 renderModules 后的遗留,白占体积 + 误导维护低(不可达)
4hotel-booking 的 subtitle 块同 3低
5🟡 加门禁:wxml 引用的字段若在同名 ts 里零命中 ⇒ 报出来这类死绑定能自动查—

第 5 条可实现(我这次的扫描逻辑已可用),但要注意

必须剔除 wx:for-item 别名,否则全是假阳性。


七、🔴 本轮仍未覆盖(诚实标注)

未查说明
🔴 wxss 8,984 行布局/可见性问题(今晚「全变到店选购」那类土壤)
🟠 wxml 条件渲染的真假逻辑本轮只查「字段存不存在」,没查 wx:if 条件是否写对
🟠 19 处分类标签是否与库中真实分类一致上一份报告里标注的
🔴 C 端 18 个页面真机行为0 页做过
🔴 normalize.ts 字段映射未查

⇒ 这份报告可用于「死绑定」维度,不能当作「wxml 已审查」。

八、我在这轮的一个错(记录)

第一版扫描没剔除 wx:for-item 别名,报出 26 个「未声明字段」,

其中 e / tk_0 / a / c 全是循环变量别名。

发现方式:去核一条 item-detail 时发现 wxml 明明写着 wx:for-item="e"。

⇒ 🔴 正则类结论必须先自证一条已知样本,否则会把「工具的错」当成「代码的错」。

这已经是今晚第三次(except 正则、--changed 扫到自己、这次的循环别名)。