This commit is contained in:
Neo
2026-03-15 10:15:02 +08:00
parent 2dd217522c
commit 72bb11b34f
916 changed files with 65306 additions and 16102803 deletions

View File

@@ -0,0 +1,308 @@
# 视图层WXML / WXSS / WXS
> 官方文档https://developers.weixin.qq.com/miniprogram/dev/framework/view/
## WXML — 模板语法
### 数据绑定
```xml
<!-- 简单绑定 -->
<view>{{ message }}</view>
<!-- 组件属性绑定(需在双引号内) -->
<view id="item-{{id}}"></view>
<!-- 控制属性绑定 -->
<view wx:if="{{condition}}"></view>
<!-- 关键字绑定(注意 true/false 需要在 {{}} 内) -->
<checkbox checked="{{false}}"></checkbox>
<!-- ⚠️ 错误写法checked="false" 会被当作字符串 "false",结果为 true -->
<!-- 运算 -->
<view>{{ a + b }} + {{ c }} + d</view>
<view>{{"hello " + name}}</view>
<view>{{object.key}} {{array[0]}}</view>
<!-- 三元运算 -->
<view hidden="{{flag ? true : false}}">Hidden</view>
<!-- 组合(数组) -->
<view wx:for="{{[zero, 1, 2, 3, 4]}}">{{item}}</view>
<!-- 组合(对象) -->
<template is="objectCombine" data="{{for: a, bar: b}}"></template>
<!-- 展开运算符 -->
<template is="objectCombine" data="{{...obj1, ...obj2, e: 5}}"></template>
```
### 列表渲染 wx:for
```xml
<!-- 基本用法:默认 item 和 index -->
<view wx:for="{{array}}">
{{index}}: {{item.message}}
</view>
<!-- 自定义变量名 -->
<view wx:for="{{array}}" wx:for-index="idx" wx:for-item="itemName">
{{idx}}: {{itemName.message}}
</view>
<!-- 嵌套 -->
<view wx:for="{{[1, 2, 3, 4, 5, 6, 7, 8, 9]}}" wx:for-item="i">
<view wx:for="{{[1, 2, 3, 4, 5, 6, 7, 8, 9]}}" wx:for-item="j">
<view wx:if="{{i <= j}}">
{{i}} * {{j}} = {{i * j}}
</view>
</view>
</view>
<!-- ⚠️ wx:key 非常重要,用于列表项的唯一标识 -->
<!-- 值为字符串item 的某个 property 名(该 property 值需唯一) -->
<switch wx:for="{{objectArray}}" wx:key="unique">{{item.id}}</switch>
<!-- 值为 *thisitem 本身是唯一字符串或数字 -->
<switch wx:for="{{numberArray}}" wx:key="*this">{{item}}</switch>
```
**wx:key 的作用**:当数据改变触发重新渲染时,带有 key 的组件会被重新排序而非重新创建,保持自身状态(如 `<input>` 的输入内容、`<switch>` 的选中状态)。
### 条件渲染
```xml
<!-- wx:if / wx:elif / wx:else -->
<view wx:if="{{length > 5}}">1</view>
<view wx:elif="{{length > 2}}">2</view>
<view wx:else>3</view>
<!-- block wx:if不会渲染为真实 DOM -->
<block wx:if="{{true}}">
<view>view1</view>
<view>view2</view>
</block>
```
**wx:if vs hidden**
- `wx:if` 是惰性的,条件为 false 时不渲染,切换时销毁/重建
- `hidden` 始终渲染,只是切换显示/隐藏(类似 CSS display:none
- 频繁切换用 `hidden`,运行时条件不大可能改变用 `wx:if`
### 模板 template
```xml
<!-- 定义模板 -->
<template name="msgItem">
<view>
<text>{{index}}: {{msg}}</text>
<text>Time: {{time}}</text>
</view>
</template>
<!-- 使用模板 -->
<template is="msgItem" data="{{...item}}"/>
<!-- 动态模板名 -->
<template is="{{item % 2 == 0 ? 'even' : 'odd'}}"/>
```
### 引用
```xml
<!-- import引入目标文件中定义的 template -->
<import src="item.wxml"/>
<template is="item" data="{{text: 'forbar'}}"/>
<!-- ⚠️ import 有作用域:只会引入目标文件中定义的 template不会引入目标文件 import 的 template不递归 -->
<!-- include将目标文件除 <template/> <wxs/> 外的整个代码引入 -->
<include src="header.wxml"/>
<view>body</view>
<include src="footer.wxml"/>
```
## WXSS — 样式
### rpx 单位
rpxresponsive pixel可以根据屏幕宽度进行自适应。规定屏幕宽为 750rpx。
| 设备 | rpx 换算 px | px 换算 rpx |
|------|------------|------------|
| iPhone5 | 1rpx = 0.42px | 1px = 2.34rpx |
| iPhone6 | 1rpx = 0.5px | 1px = 2rpx |
| iPhone6 Plus | 1rpx = 0.552px | 1px = 1.81rpx |
**建议**:开发时以 iPhone6 为视觉稿标准750px 宽1px = 1rpx。
### 样式导入
```css
/* common.wxss */
.small-p { padding: 5px; }
/* app.wxss */
@import "common.wxss";
.middle-p { padding: 15px; }
```
### 选择器支持
| 选择器 | 示例 | 说明 |
|--------|------|------|
| .class | `.intro` | 类选择器 |
| #id | `#firstname` | ID 选择器 |
| element | `view` | 元素选择器 |
| element, element | `view, checkbox` | 群组选择器 |
| ::after | `view::after` | 伪元素 |
| ::before | `view::before` | 伪元素 |
### 内联样式
```xml
<!-- style动态样式运行时解析尽量避免静态样式写在 style 中 -->
<view style="color:{{color}};"/>
<!-- class静态样式写在 class 中 -->
<view class="normal_view"/>
```
### 全局样式与局部样式
- `app.wxss` 为全局样式,作用于每个页面
- 页面的 `.wxss` 只对当前页面生效,会覆盖 `app.wxss` 中相同的选择器
## WXSWeiXin Script
WXS 是小程序的一套脚本语言,可以在 WXML 中使用。**WXS 运行在视图层**,比 JS 逻辑层快(不需要跨线程通信)。
```xml
<!-- 内联 WXS -->
<wxs module="m1">
var msg = "hello world";
module.exports.message = msg;
</wxs>
<view>{{m1.message}}</view>
<!-- 外部 WXS 文件 -->
<wxs src="./tools.wxs" module="tools"/>
<view>{{tools.msg}}</view>
<view>{{tools.bar(tools.FOO)}}</view>
```
```javascript
// tools.wxs
var foo = "'hello world' from tools.wxs"
var bar = function(d) {
return d
}
module.exports = {
FOO: foo,
bar: bar,
}
// ⚠️ WXS 不支持 ES6 语法箭头函数、let/const、解构等
// ⚠️ WXS 中不能调用小程序 APIwx.xxx
```
**WXS 典型用途**
- 格式化数据(日期、金额、文本截断)
- 在视图层做简单计算,避免 setData 开销
- 响应事件WXS 事件响应iOS 上性能更好)
## 事件系统
### 事件分类
| 类型 | 说明 | 示例 |
|------|------|------|
| 冒泡事件 | 向父节点传递 | tap, longpress, touchstart, touchmove, touchend, touchcancel |
| 非冒泡事件 | 不向父节点传递 | submit, input, scroll 等组件特有事件 |
### 事件绑定
```xml
<!-- bind不阻止冒泡 -->
<view bindtap="handleTap">Click me</view>
<view bind:tap="handleTap">Click me</view>
<!-- catch阻止冒泡 -->
<view catchtap="handleTap">Click me</view>
<!-- mut-bind互斥事件绑定基础库 2.8.2+ -->
<view mut-bind:tap="handleTap">
<button mut-bind:tap="handleButtonTap">按钮</button>
</view>
<!-- 同一冒泡路径上的 mut-bind 只会有一个被触发 -->
<!-- capture-bind捕获阶段绑定 -->
<view capture-bind:tap="handleCapture">
<view bindtap="handleTap">inner</view>
</view>
<!-- capture-catch捕获阶段中断 -->
<view capture-catch:tap="handleCapture">
<view bindtap="handleTap">inner不会触发</view>
</view>
```
### 事件对象
```javascript
Page({
handleTap(e) {
e.type // 事件类型,如 "tap"
e.timeStamp // 事件生成时的时间戳
e.target // 触发事件的源组件(可能是子组件)
e.currentTarget // 事件绑定的当前组件
e.detail // 额外信息,如 tap 的 { x, y }
e.touches // 触摸事件的触摸点信息数组
e.changedTouches // 变化的触摸点信息数组
e.mark // 事件标记(基础库 2.7.1+
// target 和 currentTarget 的区别
e.target.id // 触发事件的组件 id
e.target.dataset // 触发事件的组件的 data-xxx 属性集合
e.currentTarget.id // 绑定事件的组件 id
e.currentTarget.dataset
}
})
```
### dataset
```xml
<!-- data-xxx 属性传递数据 -->
<view data-alpha-beta="1" data-alphaBeta="2" bindtap="handleTap">
Click
</view>
```
```javascript
handleTap(e) {
e.currentTarget.dataset.alphaBeta // "1"(连字符转驼峰)
e.currentTarget.dataset.alphabeta // "2"(大写转小写)
}
```
### mark基础库 2.7.1+
```xml
<!-- mark 可以在冒泡路径上所有节点收集 -->
<view mark:myMark="last" bindtap="bindViewTap">
<button mark:anotherMark="leaf" bindtap="bindButtonTap">按钮</button>
</view>
```
```javascript
bindButtonTap(e) {
e.mark // { myMark: "last", anotherMark: "leaf" }
// mark 会合并冒泡路径上所有的 mark
}
```
## 在线查询
如需更详细信息,可抓取:
- WXML 语法https://developers.weixin.qq.com/miniprogram/dev/reference/wxml/
- WXSShttps://developers.weixin.qq.com/miniprogram/dev/framework/view/wxss.html
- WXShttps://developers.weixin.qq.com/miniprogram/dev/reference/wxs/
- 事件https://developers.weixin.qq.com/miniprogram/dev/framework/view/wxml/event.html