这是审查里标「🔴 完全未查」的三块之一。
查出 11 处死绑定,其中 2 处会展示编造文案给客人。
| 项 | 结论 |
|---|---|
| wxml 文件 | 64 个 / 2,951 行 |
| 死绑定(ts 从未赋值) | 🔴 11 处真死代码 + 5 处无害 |
| 🔴 会展示编造文案的 | 2 处(key-route 的标题与副标题) |
| 其余 | 永久不渲染的死块,白占体积 + 误导后续维护 |
对每个 X.wxml + X.ts 配对:
{{field}} 的主字段wx:for-item / wx:for-index 声明的别名(否则 e/tk_0 全是假阳性).ts 里 \bfield\b 全文搜索 —— 零命中 = 死绑定⚠️ 第一版我犯的错:没剔除循环别名 ⇒ 报出 26 个「未声明」,
其中 e/tk_0/a/c 全是 wx:for-item="e" 这类别名。
发现方式:去查一条 item-detail 时发现 wxml 明明有 wx:for-item="e"。
⇒ 加上别名剔除后才是上表的 16 处。
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 恒为空 ⇒ 必然走兜底 ⇒
客人每次看到「神山衣领 · 转山钥匙」和那段文案,而这些从未被任何数据驱动过。
⚠️ 与今晚已修的「阿里故事」是同一类问题,但更隐蔽:
「阿里故事」是过期值,这个是从没存在过的值。
建议:要么真给这两个字段赋上值(数据里取),要么删掉兜底、改为空态。
不能保留一段「永远显示的固定文案」 —— 它看起来像有内容,实际是死的。
renderModules 驱动后,旧模板没删item-detail.ts / product-detail.ts 已改成模块化渲染:
renderModules: [] as any[], // 通用模块渲染 VM(按 tpl 动态分发)
<block wx:for="{{renderModules}}" wx:key="id"> <!-- L134,新路径 -->
但 wxml 里还留着旧的直引用块:
| 文件 | 死字段 | 守卫 | 结果 | ||
|---|---|---|---|---|---|
item-detail.wxml | text(12 处引用) | wx:if="{{text}}" | 恒空 ⇒ 永不渲染 | ||
item-detail.wxml | images | wx:if="{{images.length}}" | ⚠️ .length 也会抛错 | ||
item-detail.wxml | entries | wx:for="{{entries}}" | 恒空 | ||
product-detail.wxml | 同上 3 个 + videoUrl | wx:if="{{videoUrl}}" | 恒空 | ||
hotel-booking.wxml | subtitle | wx:if="{{subtitle}}" | 恒空 | ||
sel-header.wxml | cfg.planTitle / cfg.planDesc | `{{cfg.planTitle \ | \ | '…'}}` | ⚠️ cfg 本身不存在 ⇒ cfg.planTitle 报错 ⇒ 走兜底,显示编造文案 |
key-route.wxml | routeTitle / 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(微信的容错会让整块消失,但仍是隐患)。
originY 出现在 orders / agreement / feedback / passport / journey 五处:
style="--mo-origin-y:{{originY||'100%'}}"
🔴 ts 里没有 originY,但有 || '100%' 兜底 ⇒ 结果正确(默认位置)。
保留即可,不属于缺陷。
| # | 改动 | 理由 | 风险 |
|---|---|---|---|
| 1 | key-route:给 routeTitle/routeSub 真实赋值,或删掉兜底改空态 | 🔴 客人看到的是从未存在过的文案 | 低 |
| 2 | sel-header:补 properties: { cfg: Object } 或删掉 cfg 引用 | 🔴 同上,且属性求值会抛错 | 低 |
| 3 | 删 item-detail / product-detail 里 6 处旧块 | 改 renderModules 后的遗留,白占体积 + 误导维护 | 低(不可达) |
| 4 | hotel-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 扫到自己、这次的循环别名)。