# 第3次课 讲稿

> 课程：小程序开发
> 主题：WXML模板语法与数据绑定
> 教材：《微信小程序开发实战（第2版）》第2章
> 时长：3学时（理论 1 + 实践 2）
> 重点：WXML语法、数据绑定、列表渲染、条件渲染
> 难点：列表渲染key的作用、条件渲染与列表渲染组合

---

## 一、开场（0:00）

从今天开始进入第2章，我们要真正写页面了。

先看一段代码：`<view>{{message}}</view>`。这个双花括号，是整个小程序开发里出现频率最高的东西。

（在开发者工具里现场演示：改 js 里的 message，页面文字跟着变）

大家注意我刚才做了什么——我只改了 js 里的数据，一个字的 wxml 都没动，页面就变了。这就是**数据驱动**：你不再直接去改页面，而是改数据，让框架帮你改页面。

如果同学们学过 jQuery，那种 `$('#box').text('新内容')` 的写法，在小程序里是不存在的。今天要完成的思维转变就是：**从"操作页面"转到"维护数据"**。

---

## 二、明确本课目标（约 5:00）

把目标写在白板上或直接翻到课件第 2 页，逐条念一遍：

- 掌握WXML模板语法的基本用法
- 理解数据绑定的原理与单向/双向绑定
- 掌握列表渲染 wx:for 与条件渲染 wx:if
- 能够使用数据绑定实现动态页面
- 案例：案例2-1 个人信息

本次课 3 学时的安排是：**理论讲解 1 学时，上机实践 2 学时**——模板语法讲解 1 学时，案例 2-1 个人信息实操 2 学时。

---

## 三、知识点讲解

### 幻灯片 3：数据绑定 {{}}

**【8:00 讲解】**

**Mustache语法 {{}}**

在WXML中绑定数据

- 绑定文本内容: <text>{{message}}</text>
- 绑定属性: <image src="{{imageUrl}}"></image>
- 绑定样式: style="color:{{colorVal}}"
- 运算支持: 算术/三元/逻辑/字符串运算

### 幻灯片 4：列表渲染 wx:for

**【13:00 讲解】**

**wx:for**

根据数组重复渲染组件

**wx:key**

指定列表项唯一标识(提升性能)

- 默认变量: item(当前项) 和 index(下标)
- 自定义变量名: wx:for-item / wx:for-index
- 嵌套循环时务必自定义变量名避免冲突

### 幻灯片 5：条件渲染 wx:if

**【18:00 讲解】**

**wx:if**

条件为true时渲染该组件

**wx:elif / wx:else**

多条件分支

- wx:if vs hidden: wx:if会销毁/重建, hidden只是切换显示
- 频繁切换用hidden, 条件很少变用wx:if
- wx:if 作用于单个组件, block wx:if 作用于多个

### 幻灯片 6：案例2-1 个人信息

**【23:00 讲解】**

- 使用数据绑定展示个人信息(姓名/头像/简介)
- 使用列表渲染展示技能标签
- 使用条件渲染控制VIP标识显示
- 使用wx:for展示教育经历时间线
- 综合运用WXML核心语法完成页面搭建

---

## 四、难点突破：用类比讲清楚

下面这几个点是学生最容易卡住的地方，抽象讲不通就换成类比。

### 数据绑定

像 Word 的邮件合并：模板里写"尊敬的{姓名}"，数据表里换一行，打印出来的信就换一个人。WXML 是模板，data 是数据表，框架负责合并。

### wx:key 的作用

想象一个班级排队，每个人手里举着学号牌。中间插进来一个人，老师看学号牌就知道谁是谁，只需要挪一个位置；如果没有学号牌，老师只能让所有人重新站一遍。wx:key 就是那块学号牌，它让框架知道哪些节点可以复用。

### wx:if 与 hidden 的区别

wx:if 是"把家具搬走"，hidden 是"拿块布盖上"。搬走省地方但搬来搬去费劲，盖布不费劲但一直占着空间。所以频繁切换用 hidden，很少变化用 wx:if。

---

## 五、代码演示环节

以下每一段都建议**现场敲**，不要直接贴完整代码。边敲边问"下一行该写什么"，让学生跟上节奏。

### 演示 1：数据绑定 {{}}

**文件：** `index.wxml`　**预期效果：** 数据绑定效果

```html
<!-- 1. 简单数据绑定 -->
<view>{{message}}</view>

<!-- 2. 属性绑定 -->
<image src="{{imageUrl}}"></image>
<view id="item-{{id}}"></view>

<!-- 3. style 动态绑定 -->
<view style="color:{{color}};">彩色文字</view>
<view style="width:{{width}}rpx;height:{{height}}rpx;">
尺寸可变盒子
</view>

<!-- 4. class 动态绑定 -->
<view class="box {{isActive ? 'active' : ''}">
条件样式
</view>

<!-- 5. 表达式运算 -->
<view>{{a + b}}</view>
<view>{{len > 10 ? '长' : '短'}}</view>
<view>{{name.firstName}}</view>
<view>{{'Hello ' + user}}</view>

<!-- ⚠️ 注意：不能调用函数 -->
<!-- {{formatDate(time)}} ❌ 不支持 -->
<!-- 需用 wxs 或在 js 中预处理 -->
```

**讲解口径：**

WXML使用**双花括号{{}}**进行数据绑定。支持五种用法：**内容绑定**{{message}}、**属性绑定**如src="{{url}}"、**style动态绑定**、**class条件绑定**、以及**表达式运算**如加减、三元运算、对象属性访问。注意**不能在{{}}中调用函数**，需要用wxs或在js中预处理数据。

### 演示 2：列表渲染 wx:for

**文件：** `list.wxml`　**预期效果：** 列表渲染效果

```html
<!-- 1. 基础 wx:for 用法 -->
<view wx:for="{{users}}">
索引：{{index}}，值：{{item}}
</view>

<!-- 2. wx:key 提升渲染性能 -->
<view wx:for="{{users}}" wx:key="id">
{{item.name}}
</view>

<!-- 3. 自定义变量名 -->
<view
wx:for="{{users}}"
wx:for-item="user"
wx:for-index="idx"
wx:key="id">
{{idx}} - {{user.name}}
</view>

<!-- 4. 嵌套循环 -->
<view wx:for="{{matrix}}" wx:for-item="row">
<view wx:for="{{row}}" wx:for-item="cell">
{{cell}}
</view>
</view>

<!-- 5. block 包装多节点 -->
<block wx:for="{{items}}" wx:key="id">
<view>标题：{{item.title}}</view>
<view>内容：{{item.desc}}</view>
</block>

<!-- ⚠️ wx:key 必须唯一且稳定 -->
<!-- wx:key="*this" 用于简单数组 -->
```

**讲解口径：**

wx:for用于列表渲染，默认提供**index**索引和**item**当前项。强烈建议添加**wx:key**提升列表更新性能，值应为唯一标识如id。嵌套循环时用**wx:for-item和wx:for-index**自定义变量名避免冲突。**block标签**可包裹多个节点而不产生额外DOM。简单数组可用**wx:key="*this"**。

### 演示 3：条件渲染 wx:if

**文件：** `condition.wxml`　**预期效果：** 条件渲染对比

```html
<!-- 1. wx:if / wx:elif / wx:else -->
<view wx:if="{{score >= 90}}">优秀</view>
<view wx:elif="{{score >= 60}}">及格</view>
<view wx:else>不及格</view>

<!-- 2. block + wx:if 控制多节点 -->
<block wx:if="{{isVip}}">
<view>VIP专属内容</view>
<view>折扣信息</view>
</block>

<!-- 3. hidden 属性 -->
<view hidden="{{!isShow}}">隐藏内容</view>

<!-- ⚠️ wx:if vs hidden 区别 -->
wx:if  → 条件为false时，节点不渲染（销毁/创建）
hidden → 条件为false时，节点已渲染（display:none）

<!-- 选型建议 -->
<!-- 频繁切换 → 用 hidden（避免反复创建销毁） -->
<!-- 条件很少变 → 用 wx:if（节省初始渲染开销） -->
```

**讲解口径：**

条件渲染用**wx:if、wx:elif、wx:else**，条件为false时节点不会渲染到DOM中。**hidden**则不同，节点始终在DOM中，只是通过display:none隐藏。选型建议：**频繁切换用hidden**避免反复创建销毁的开销，**条件很少变化用wx:if**节省初始渲染开销。block标签配合wx:if可控制多个节点的显示。

### 演示 4：案例2-1 个人信息展示

**文件：** `person.wxml`　**预期效果：** 个人信息页效果

```html
<!-- 案例2-1：个人信息展示页 -->
<view class="container">

<!-- 头像区域 -->
<image
class="avatar"
src="{{avatarUrl}}"
mode="aspectFill"
/>

<!-- 姓名与签名 -->
<view class="name">{{name}}</view>
<view class="signature">{{signature}}</view>

<!-- 技能标签（wx:for） -->
<view class="skills">
<view
wx:for="{{skills}}"
wx:key="*this"
class="skill-tag">
{{item}}
</view>
</view>

<!-- 联系方式（wx:if） -->
<view class="contact">
<view wx:if="{{phone}}">
📞 {{phone}}
</view>
<view wx:if="{{email}}">
📧 {{email}}
</view>
</view>

</view>

// 对应 index.js 数据
Page({
data: {
avatarUrl: "/images/avatar.png",
name: "张三",
signature: "热爱编程，热爱生活",
skills: ["WXML", "WXSS", "JS"],
phone: "13800138000",
email: "zhangsan@qq.com"
}
})
```

**讲解口径：**

案例2-1综合运用了三种模板语法：**{{}}**数据绑定显示姓名、签名和头像；**wx:for**循环渲染技能标签列表，使用wx:key="*this"；**wx:if**条件渲染联系方式，只有phone和email有值时才显示。这个案例体现了WXML模板语法的核心用法：**数据驱动视图**。

---

## 六、常见错误与排查

上机环节学生一定会遇到下面这些问题，提前讲一遍能省掉大量重复答疑。

| # | 现象 | 原因与解决 |
|:-:|------|------------|
| 1 | 在 {{}} 里调用函数 | `{{formatDate(time)}}` 是不支持的，会直接报错。要么在 js 里预处理好再 setData，要么用 wxs。这是从 Vue 转过来的同学最容易犯的错。 |
| 2 | wx:for 用 index 当 key | 列表中间插入或删除时 index 会变，等于没设 key。应该用数据里稳定的唯一字段，比如 id。 |
| 3 | 直接修改 this.data | `this.data.list.push(x)` 不会触发渲染。必须走 setData。这个错误课上一定会有人犯，建议提前埋一个演示。 |
| 4 | 嵌套 wx:for 变量名冲突 | 内外层都用默认的 item，内层会覆盖外层。嵌套时务必用 wx:for-item 自定义变量名。 |

---

## 七、上机实践指引

本次课对应教材案例 1 个，源码已放在站点 `code/session03/` 下：

- **【案例2-1】个人信息** — 含 知识储备、案例实现 共 2 个工程

建议顺序：先带学生跑一遍「知识储备」里的最小示例，确认每个知识点都能单独跑通，再进「案例实现」做完整案例。直接上完整案例，出错了不知道错在哪。

---

## 八、本课小结

回到课件小结页，逐条回顾：

- 数据绑定 {{}}
- 列表渲染 wx:for
- 条件渲染 wx:if
- 案例2-1 个人信息展示

今天三个语法：数据绑定、列表渲染、条件渲染。它们会出现在你之后写的每一个页面里。

案例2-1 个人信息一定要自己敲一遍，光看不敲是记不住的。特别提醒：写 wx:for 的时候，wx:key 别偷懒。

---

## 九、布置作业

三档任务，基础必做，进阶建议做，挑战选做。

### 【基础】完成个人信息页面

按照案例2-1，完成个人信息展示页面，包含头像、姓名、学校、专业等信息

### 【进阶】扩展个人信息

在案例2-1基础上，增加联系方式、兴趣爱好等字段，使用三元运算符控制显示

### 【挑战】可筛选的技能列表

在个人信息页基础上，用 wx:for 渲染技能标签、wx:if 按熟练度筛选，观察加/不加 wx:key 时列表复用的差异

---

> 配套资源：课件 `slides-v2/session03.pptx`　课堂视频 `videos-output/session03.mp4`　扩展阅读 `docs/第3次课_扩展阅读.md`
