微信小程序提供了视图容器组件、基础内容组件、表单组件、操作反馈组件、导航组件、媒体组件、地图组件、画布组件等8类组件,包括了大部分UI需要用到的组件。
组件的通用属性
1.id属性
id属性为字符串类型(String),是组件的唯一标示,在同一页面中id属性必须保持唯一,不能重复。
id 用于定位:仅用于获取组件实例或CSS锚点,不要用于样式选择器(性能差)
2.class属性
class 属性为字符串类型(String),通过class属性来设置组件的样式类。该属性的值为样式类名称,该样式类的CSS样式定义在对应的WXSS文件中。如果与动态数据绑定相结合,组件的class也将具有动态变换的能力。
3.style属性
style属性为字符串类型(String),通过style属性可设置组件的内联样式。style属性值中可设置CSS的各种属性。如果与动态数据绑定相结合,组件的style也将具有动态变换的能力。
样式优先用 class:静态样式用 class,动态样式用 style
4. hidden 属性
hidden属性是一个逻辑值(Boolean),用来决定该组件是否显示。默认情况下,hidden属性的值为false,即组件为显示状态(不隐藏)。
隐藏用 hidden:频繁切换用 hidden,初始不显示用 wx:if
5.data-*属性
data-*属性可为任何类型,可用来为组件设置任意的自定义属性值。当组件上绑定的事件触发时,这些自定义属性将作为参数发送给事件处理函数,在事件处理函数中可通过传人参数对象的currentTarget.dataset方式来获取自定义属性的值。
html
<!-- 传递多个数据 -->
<button
data-user-id="12345"
data-user-name="张三"
data-user-age="25"
bindtap="handleUserInfo"
>
传递用户信息
</button>
<!-- 支持驼峰命名(会自动转小写) -->
<view data-userName="李四" data-userAge="30" bindtap="handleData">
测试驼峰命名
</view>
javascript
Page({
handleUserInfo(event) {
// 通过 currentTarget.dataset 获取
const userId = event.currentTarget.dataset.userId; // "12345"
const userName = event.currentTarget.dataset.userName; // "张三"
const userAge = event.currentTarget.dataset.userAge; // "25"
console.log(userId, userName, userAge);
},
handleData(event) {
// 驼峰命名会自动转小写
console.log(event.currentTarget.dataset.username); // "李四"
console.log(event.currentTarget.dataset.userage); // "30"
}
});
注意事项:
-
属性名中不能有大写字母,如需使用驼峰,实际会转为小写
-
建议全部使用小写加短横线:
data-user-name
数据传递用 data-*:简单数据传递优先使用 dataset
冒泡数据用 mark:需要多层级数据时使用 mark
6. bind* / catch* 事件绑定
用来为组件定义事件,bind和 catch的区别是,bind事件绑定不会阻止冒泡事件向上冒泡,catch事件绑定可以阻止冒泡事件向上冒泡。
html
<!-- bind:事件会冒泡 -->
<view bindtap="parentTap">
<button bindtap="childTap">冒泡事件</button>
</view>
<!-- catch:阻止冒泡 -->
<view bindtap="parentTap">
<button catchtap="childTap">阻止冒泡</button>
</view>
<!-- 支持事件类型后缀 -->
<input bindinput="onInput" bindfocus="onFocus" bindblur="onBlur" />
<scroll-view bindscroll="onScroll" />
7. mut-bind:* 互斥绑定
同一节点上多个互斥绑定事件,只会触发其中一个。
html
<!-- 点击时只会触发一个(通常是最外层的或特定规则) -->
<view mut-bind:tap="handleTap1" mut-bind:tap="handleTap2">
互斥绑定测试
</view>
8. capture-bind:* / capture-catch:* 捕获阶段事件
执行顺序: 捕获阶段(从外到内)→ 目标阶段 → 冒泡阶段(从内到外
html
<!-- 捕获阶段绑定(先于冒泡阶段执行) -->
<view capture-bind:tap="captureTap">
<view bindtap="bubbleTap">点击测试</view>
</view>
<!-- 捕获阶段阻止事件传递 -->
<view capture-catch:tap="captureStopTap">
<view bindtap="bubbleTap">不会触发bubbleTap</view>
</view>
9. mark:* 标记数据
与 data-* 类似,但 mark 数据会在冒泡时合并传递。
html
<view mark:parentId="p001" bindtap="parentTap">
<button mark:childId="c001" bindtap="childTap">点击</button>
</view>
javascript
Page({
childTap(event) {
// 可以同时获取父组件和子组件的 mark 数据
console.log(event.mark.parentId); // "p001"
console.log(event.mark.childId); // "c001"
},
parentTap(event) {
console.log(event.mark.parentId); // "p001"
console.log(event.mark.childId); // undefined(从子组件冒泡过来才有)
}
});
mark 与 dataset 的区别:
-
dataset:只包含当前组件的data-*数据 -
mark:包含冒泡路径上所有组件的mark:*数据(会合并)
视图容器组件
视图容器组件包括view、scroll-view、swiper及swiper-item,主要用于控制视图样式与内容展现。
用于布局和结构组织的基础组件,它们负责承载其他组件、控制布局方式以及实现滚动、轮播等高级交互功能。
| 组件名 | 主要功能 | 适用场景 |
|---|---|---|
<view> |
基础容器,类似div | 普通布局、结构划分 |
<block> |
逻辑容器,不渲染 | 批量渲染、条件判断 |
<scroll-view> |
可滚动视图 | 长列表、横向滚动、滚动动画 |
<swiper> |
轮播容器 | 图片轮播、卡片滑动、引导页 |
<movable-view> |
可移动容器 | 拖拽排序、悬浮窗 |
<cover-view> |
覆盖原生组件 | 地图、视频上叠加文本/按钮 |
<page-container> |
页面级容器 | 弹窗、抽屉、半屏效果 |
<share-element> |
共享元素动画 | 页面转场动画 |
1. <view> - 基础容器
最基础的视图容器,功能类似于 HTML 的 <div>,用于布局、分组和样式控制。
特殊属性:
-
hover-class:点击时的样式类(默认none) -
hover-stop-propagation:阻止点击状态向父节点传递 -
hover-start-time:点击后多久出现点击态(单位ms) -
hover-stay-time:点击态保持时间(单位ms)
html
<view
hover-class="view-hover"
hover-start-time="50"
hover-stay-time="400"
hover-stop-propagation="{{true}}"
>
带点击反馈的视图
</view>
2. <block> - 逻辑容器
不渲染 任何节点的包装器,只用于逻辑控制(条件、循环)。不支持 class、style、id 等样式属性,因为它不会被渲染到DOM中。
html
<!-- 条件渲染 -->
<block ="{{hasPermission}}">
<view>管理员菜单1</view>
<view>管理员菜单2</view>
</block>
<!-- 列表渲染 -->
<block ="{{userList}}" ="id">
<view class="user-item">{{item.name}}</view>
<view class="user-desc">{{item.desc}}</view>
</block>
<!-- 混合使用 -->
<block ="{{showSection}}">
<block ="{{items}}" ="index">
<view>{{item}}</view>
</block>
</block>
3. <scroll-view> - 可滚动视图
实现区域滚动,支持横向、纵向滚动,常用于长列表、横向滑动菜单。
html
<!-- 纵向滚动 -->
<scroll-view
scroll-y="{{true}}"
style="height: 500rpx;"
bindscrolltolower="loadMore"
lower-threshold="50"
>
<view ="{{100}}" ="index">列表项 {{index}}</view>
</scroll-view>
<!-- 横向滚动 -->
<scroll-view
scroll-x="{{true}}"
class="horizontal-scroll"
bindscroll="onScroll"
>
<view class="scroll-item" ="{{banners}}" ="id">
<image src="{{item.image}}" mode="widthFix" />
</view>
</scroll-view>
<!-- 滚动到指定位置 -->
<scroll-view
scroll-y="{{true}}"
scroll-into-view="item-{{currentIndex}}"
scroll-with-animation="{{true}}"
>
<view id="item-0">项目0</view>
<view id="item-1">项目1</view>
<view id="item-2">项目2</view>
</scroll-view>
常用属性:
| 属性 | 类型 | 说明 |
|---|---|---|
scroll-x |
Boolean | 允许横向滚动 |
scroll-y |
Boolean | 允许纵向滚动 |
scroll-top |
Number | 设置竖向滚动条位置 |
scroll-left |
Number | 设置横向滚动条位置 |
scroll-into-view |
String | 滚动到指定id的元素 |
scroll-with-animation |
Boolean | 滚动时使用动画 |
bindscrolltolower |
EventHandle | 滚动到底部/右边触发 |
lower-threshold |
Number | 距底部多远触发(默认50) |
bindscroll |
EventHandle | 滚动时触发 |
4. <swiper> - 轮播容器
实现触摸滑动轮播效果,常用于首页Banner、卡片轮播。
html
<!-- 基础轮播 -->
<swiper
indicator-dots="{{true}}"
autoplay="{{true}}"
interval="3000"
duration="500"
circular="{{true}}"
bindchange="onSwiperChange"
>
<swiper-item ="{{banners}}" ="id">
<image src="{{item.image}}" mode="aspectFill" class="banner-img" />
</swiper-item>
</swiper>
<!-- 垂直轮播 -->
<swiper
vertical="{{true}}"
indicator-dots="{{true}}"
autoplay="{{true}}"
style="height: 200rpx;"
>
<swiper-item>
<view class="notice-item">公告1:系统升级通知</view>
</swiper-item>
<swiper-item>
<view class="notice-item">公告2:活动即将开始</view>
</swiper-item>
</swiper>
<!-- 卡片式轮播(设置间距和边距) -->
<swiper
next-margin="30rpx"
previous-margin="30rpx"
display-multiple-items="1"
>
<swiper-item ="{{cards}}" ="id">
<view class="card">{{item.title}}</view>
</swiper-item>
</swiper>
常用属性:
| 属性 | 类型 | 说明 |
|---|---|---|
indicator-dots |
Boolean | 是否显示面板指示点 |
autoplay |
Boolean | 是否自动切换 |
interval |
Number | 自动切换时间间隔(ms) |
duration |
Number | 滑动动画时长(ms) |
circular |
Boolean | 是否循环播放 |
vertical |
Boolean | 滑动方向是否为纵向 |
current |
Number | 当前所在滑块的索引 |
bindchange |
EventHandle | current改变时触发 |
5. <movable-view> - 可移动容器
需要配合 <movable-area> 使用,实现可拖拽移动的组件。
html
<!-- 基础拖拽 -->
<movable-area style="width: 600rpx; height: 600rpx; background: #f0f0f0;">
<movable-view
style="width: 100rpx; height: 100rpx; background: #07c160;"
direction="all"
bindchange="onMovableChange"
>
拖拽
</movable-view>
</movable-area>
<!-- 限制拖拽范围 -->
<movable-area style="width: 100%; height: 400rpx;">
<movable-view
x="{{x}}"
y="{{y}}"
direction="all"
out-of-bounds="{{false}}"
bindchange="onChange"
>
<view class="drag-item">可拖动</view>
</movable-view>
</movable-area>
常用属性:
-
direction:移动方向(all/vertical/horizontal/none) -
x/y:初始位置 -
out-of-bounds:是否超出边界 -
damping:阻尼系数(超出边界后)
6. <cover-view> - 覆盖原生组件
覆盖在原生组件(如 <video>、<map>、<canvas>)之上的视图。
html
<!-- 视频上叠加控件 -->
<video src="{{videoUrl}}" controls>
<cover-view class="video-controls">
<cover-view class="play-btn" bindtap="togglePlay">
{{isPlaying ? '暂停' : '播放'}}
</cover-view>
<cover-view class="time">{{currentTime}}/{{duration}}</cover-view>
</cover-view>
</video>
<!-- 地图上叠加信息 -->
<map latitude="{{latitude}}" longitude="{{longitude}}">
<cover-view class="map-marker">
<cover-image src="/images/marker.png" />
<cover-view>当前位置</cover-view>
</cover-view>
</map>
注意事项:
-
仅支持部分组件:
button、image、text、view -
不支持
overflow、position: fixed等CSS属性 -
建议使用
cover-image显示图片
7. <page-container> - 页面级容器
实现弹窗、抽屉、半屏等效果,类似于半透明遮罩层。
html
<!-- 底部弹出 -->
<button bindtap="showPopup">显示弹窗</button>
<page-container
show="{{showPopup}}"
position="bottom"
round="{{true}}"
bindafterleave="onPopupClose"
>
<view class="popup-content">
<view class="popup-header">标题</view>
<view class="popup-body">弹窗内容</view>
<button bindtap="closePopup">关闭</button>
</view>
</page-container>
javascript
Page({
data: {
showPopup: false
},
showPopup() {
this.setData({ showPopup: true });
},
closePopup() {
this.setData({ showPopup: false });
}
});
常用属性:
-
show:是否显示 -
position:弹出位置(top/bottom/left/right/center) -
round:是否显示圆角 -
overlay:是否显示遮罩层 -
close-on-slide-down:是否允许下滑关闭
基础内容组件
基础内容组件包括icon、text和progress,用于在视图界面中展现图标、文本内容及进度条等信息。用于展示最基础UI内容的组件,包括文本、图标、进度条等。它们是构建用户界面的最小单元,几乎所有页面都会用到。
| 组件名 | 主要功能 | 适用场景 |
|---|---|---|
<text> |
文本展示 | 普通文本、内联文本、长按复制 |
<icon> |
图标展示 | 状态图标、提示图标、简单图标 |
<progress> |
进度条 | 加载进度、下载进度、完成率展示 |
<rich-text> |
富文本渲染 | 渲染HTML、文章内容、格式化文本 |
<view> |
基础容器 | 布局容器(已在视图容器中介绍) |
1. <text> - 文本组件
最基础的文本展示组件,支持长按复制、嵌套等特性。
| 属性 | 类型 | 说明 |
|---|---|---|
selectable |
Boolean | 是否支持长按选中复制(默认false) |
space |
String | 显示连续空格(ensp/emsp/nbsp) |
decode |
Boolean | 是否解码HTML实体( 等) |
user-select |
Boolean | 是否支持用户选择(基础库2.12.1+) |
html
<!-- 长按复制文本 -->
<text selectable="{{true}}" user-select="{{true}}">
这段文字可以被长按复制
</text>
<!-- 显示连续空格 -->
<text space="ensp">文 本(中文空格)</text>
<text space="emsp">文 本(em空格)</text>
<text space="nbsp">文 本(不断行空格)</text>
<!-- 解码HTML实体 -->
<text decode="{{true}}">< > &    </text>
<!-- 输出: < > & -->
文本嵌套
html
<!-- text支持嵌套,内层会继承外层样式 -->
<text class="outer">
外层文本
<text class="inner" selectable>内层可复制文本</text>
继续外层文本
</text>
<!-- 实现文本截断效果 -->
<text class="ellipsis">
很长很长很长很长很长很长很长很长的文本会被截断
</text>
/* 文本截断样式 */
.ellipsis {
display: block;
width: 300rpx;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
2. <icon> - 图标组件
提供内置的图标库,无需图片资源即可使用常见图标。
可用图标类型
| type值 | 说明 | 默认颜色 |
|---|---|---|
success |
成功图标(圆形打勾) | #07c160 |
success_no_circle |
成功图标(无圆形) | #07c160 |
info |
信息图标(圆形i) | #1989fa |
warn |
警告图标(三角感叹号) | #fa2c19 |
waiting |
等待图标(圆形时钟) | #ff976a |
cancel |
取消图标(圆形叉) | #999 |
download |
下载图标 | #666 |
search |
搜索图标(放大镜) | #666 |
clear |
清除图标(叉) | #ccc |
属性说明
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
type |
String | - | 图标类型(必填) |
size |
Number/String | 23 | 图标大小(单位px) |
color |
String | 各类型默认色 | 图标颜色 |
html
<!-- 自定义大小和颜色 -->
<icon type="success" size="32" color="#ff6600" />
<icon type="info" size="20" color="#00b26a" />
<!-- 结合文本使用 -->
<view class="status-item">
<icon type="success" size="16" />
<text>操作成功</text>
</view>
3. <progress> - 进度条组件
展示操作进度,支持百分比显示、动画、圆角等。
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
percent |
Number | 0 | 进度百分比(0-100) |
show-info |
Boolean | false | 是否显示百分比文字 |
stroke-width |
Number | 6 | 进度条高度(单位px) |
color |
String | #09BB07 | 进度条颜色 |
backgroundColor |
String | #EBEBEB | 背景条颜色 |
active |
Boolean | false | 是否从左到右动画 |
active-mode |
String | backwards | 动画模式(backwards/forwards) |
border-radius |
Number | 0 | 圆角大小(单位px) |
duration |
Number | 30 | 动画持续时间(ms) |
html
<!-- 简单进度条 -->
<progress percent="30" />
<!-- 带文字百分比 -->
<progress percent="50" show-info stroke-width="8" />
<!-- 自定义颜色 -->
<progress
percent="75"
color="#1989fa"
backgroundColor="#e5e5e5"
stroke-width="10"
border-radius="5"
/>
<!-- 带动画效果 -->
<progress
percent="{{progressPercent}}"
active="{{true}}"
active-mode="forwards"
duration="1000"
show-info
/>
javascript
Page({
data: {
progressPercent: 0
},
onLoad() {
// 模拟进度更新
let progress = 0;
const timer = setInterval(() => {
progress += 10;
this.setData({ progressPercent: progress });
if (progress >= 100) {
clearInterval(timer);
}
}, 500);
}
});
4. <rich-text> - 富文本组件
用于渲染HTML字符串,支持常见的HTML标签和样式。
html
<!-- 基础HTML渲染 -->
<rich-text nodes="<h1>标题</h1><p>这是一个段落</p>" />
<!-- 通过数据绑定 -->
<rich-text nodes="{{htmlContent}}" />
javascript
Page({
data: {
htmlContent: `
<div style="padding: 20rpx;">
<h2 style="color: #333;">文章标题</h2>
<p style="font-size: 28rpx; line-height: 1.6;">
这是一段<span style="color: red;">高亮文字</span>。
</p>
<img src="https://example.com/image.jpg" style="width: 100%;" />
<ul>
<li>列表项1</li>
<li>列表项2</li>
</ul>
</div>
`
}
});
nodes支持两种格式:字符串 和 数组。
表单组件
用于收集用户输入信息的重要组件,涵盖文本输入、选择器、开关、按钮等交互元素,是构建用户交互界面的核心。
| 组件名 | 主要功能 | 适用场景 |
|---|---|---|
<button> |
按钮 | 表单提交、页面跳转、授权触发 |
<input> |
输入框 | 文本、数字、密码、身份证输入 |
<textarea> |
多行输入框 | 评论、反馈、文章编辑 |
<checkbox> |
多选框 | 多项选择、协议确认 |
<radio> |
单选框 | 性别选择、选项切换 |
<switch> |
开关 | 状态切换、设置项 |
<slider> |
滑动选择器 | 音量、亮度、数值范围选择 |
<picker> |
选择器 | 日期、时间、地区、自定义选择 |
<picker-view> |
嵌入式选择器 | 三级联动、自定义滚动选择 |
<form> |
表单容器 | 批量收集表单数据 |
1. <button> - 按钮组件
最核心的交互组件,支持多种类型、尺寸和状态。
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
type |
String | default | 按钮类型(default/primary/warn) |
size |
String | default | 按钮大小(default/mini) |
plain |
Boolean | false | 是否镂空 |
disabled |
Boolean | false | 是否禁用 |
loading |
Boolean | false | 是否显示加载图标 |
form-type |
String | - | 表单类型(submit/reset) |
open-type |
String | - | 开放能力(contact/share/getPhoneNumber等) |
hover-class |
String | button-hover | 点击态样式 |
hover-stop-propagation |
Boolean | false | 阻止点击态冒泡 |
hover-start-time |
Number | 20 | 点击后多久出现点击态 |
hover-stay-time |
Number | 70 | 点击态保持时长 |
开放能力(open-type)
html
<!-- 获取用户信息 -->
<button open-type="getUserInfo" bindgetuserinfo="onGetUserInfo">
获取用户信息
</button>
<!-- 获取手机号 -->
<button open-type="getPhoneNumber" bindgetphonenumber="onGetPhoneNumber">
获取手机号
</button>
<!-- 分享 -->
<button open-type="share">分享给朋友</button>
<!-- 客服 -->
<button open-type="contact" bindcontact="onContact">
联系客服
</button>
<!-- 打开APP -->
<button open-type="launchApp">打开APP</button>
<!-- 反馈 -->
<button open-type="feedback">意见反馈</button>
javascript
Page({
onGetUserInfo(e) {
console.log(e.detail.userInfo);
},
onGetPhoneNumber(e) {
console.log(e.detail.code);
console.log(e.detail.errMsg);
}
});
2. <input> - 输入框
最常用的文本输入组件,支持多种输入类型。
| 属性 | 类型 | 说明 |
|---|---|---|
value |
String | 输入框内容 |
type |
String | 类型(text/number/idcard/digit) |
password |
Boolean | 是否密码类型 |
placeholder |
String | 占位符 |
placeholder-style |
String | 占位符样式 |
placeholder-class |
String | 占位符样式类 |
disabled |
Boolean | 是否禁用 |
maxlength |
Number | 最大长度(0不限制) |
cursor-spacing |
Number | 光标与键盘距离 |
focus |
Boolean | 自动获取焦点 |
confirm-type |
String | 键盘右下角按钮类型 |
confirm-hold |
Boolean | 点击确认按钮是否保持键盘 |
adjust-position |
Boolean | 键盘弹起时是否自动上推页面 |
hold-keyboard |
Boolean | 聚焦时点击页面不收起键盘 |
auto-fill |
String | 自动填充内容 |
3. <textarea> - 多行输入框
用于输入多行文本,如评论、反馈等场景。
html
<textarea
placeholder="请输入评论内容"
maxlength="200"
auto-height="{{true}}"
show-confirm-bar="{{false}}"
bindinput="onTextareaInput"
/>
<!-- 固定高度文本域 -->
<textarea
style="height: 200rpx;"
maxlength="500"
placeholder-style="color: #999;"
/>
常用属性:
-
auto-height:是否自动增高 -
show-confirm-bar:是否显示键盘上方完成栏 -
disable-default-padding:是否移除默认内边距
4. <checkbox> - 多选框
用于多选场景,需配合 <checkbox-group> 使用。
html
<!-- 单个多选框 -->
<checkbox-group bindchange="onCheckboxChange">
<label>
<checkbox value="agree" checked="{{isAgreed}}"/>
同意用户协议
</label>
</checkbox-group>
<!-- 多选组 -->
<checkbox-group bindchange="onHobbyChange">
<label ="{{hobbies}}" ="value">
<checkbox value="{{item.value}}" checked="{{item.checked}}"/>
{{item.name}}
</label>
</checkbox-group>
javascript
Page({
data: {
hobbies: [
{ name: '阅读', value: 'read', checked: false },
{ name: '音乐', value: 'music', checked: true },
{ name: '运动', value: 'sport', checked: false }
]
},
onHobbyChange(e) {
console.log('选中的值:', e.detail.value);
// e.detail.value: ['music', 'read']
}
});
5. <radio> - 单选框
用于单选场景,需配合 <radio-group> 使用。
html
<radio-group bindchange="onGenderChange">
<label>
<radio value="male" checked="{{gender === 'male'}}"/>
男
</label>
<label>
<radio value="female" checked="{{gender === 'female'}}"/>
女
</label>
</radio-group>
javascript
Page({
data: {
gender: 'male'
},
onGenderChange(e) {
this.setData({
gender: e.detail.value
});
}
});
6. <switch> - 开关
用于切换状态,类似设置项。
html
<switch checked="{{isEnabled}}" bindchange="onSwitchChange" />
<!-- 自定义颜色 -->
<switch
checked="{{isVibrate}}"
color="#07c160"
type="switch"
bindchange="onVibrateChange"
/>
<!-- 复选框样式 -->
<switch type="checkbox" checked="{{isSelected}}" />
javascript
Page({
data: {
isEnabled: true,
isVibrate: false
},
onSwitchChange(e) {
this.setData({
isEnabled: e.detail.value
});
}
});
7. <slider> - 滑动选择器
通过滑动选择数值,适合音量、亮度调节。
html
<!-- 基础滑块 -->
<slider value="{{50}}" bindchange="onSliderChange" />
<!-- 带边界值 -->
<slider
min="0"
max="100"
step="1"
value="{{volume}}"
show-value
bindchanging="onVolumeChanging"
bindchange="onVolumeChange"
/>
<!-- 自定义样式 -->
<slider
block-size="20"
block-color="#07c160"
active-color="#07c160"
backgroundColor="#e5e5e5"
/>
javascript
Page({
data: {
volume: 50
},
onVolumeChanging(e) {
// 拖动过程中实时触发
console.log('当前值:', e.detail.value);
},
onVolumeChange(e) {
// 拖动结束触发
this.setData({
volume: e.detail.value
});
}
});
8. <picker> - 选择器
从底部弹起的滚动选择器,支持多种模式
html
普通选择器
<picker
mode="selector"
range="{{selectorItems}}"
value="{{selectorIndex}}"
bindchange="onSelectorChange"
>
<view>当前选择:{{selectorItems[selectorIndex]}}</view>
</picker>
多列选择器
<picker
mode="multiSelector"
range="{{multiArray}}"
value="{{multiIndex}}"
bindchange="onMultiChange"
bindcolumnchange="onColumnChange"
>
<view>当前选择:{{multiArray[0][multiIndex[0]]}} - {{multiArray[1][multiIndex[1]]}}</view>
</picker>
时间选择器
<picker
mode="time"
value="{{time}}"
start="09:00"
end="18:00"
bindchange="onTimeChange"
>
<view>当前时间:{{time}}</view>
</picker>
<picker
mode="date"
value="{{date}}"
start="2020-01-01"
end="2030-12-31"
bindchange="onDateChange"
>
<view>当前日期:{{date}}</view>
</picker>
地区选择器
<picker
mode="region"
value="{{region}}"
bindchange="onRegionChange"
>
<view>当前地区:{{region[0]}} {{region[1]}} {{region[2]}}</view>
</picker>
javascript
Page({
data: {
selectorItems: ['选项1', '选项2', '选项3'],
selectorIndex: 0,
time: '12:00',
date: '2024-01-15',
region: ['广东省', '广州市', '海珠区']
},
onSelectorChange(e) {
this.setData({
selectorIndex: e.detail.value
});
},
onTimeChange(e) {
this.setData({
time: e.detail.value
});
},
onDateChange(e) {
this.setData({
date: e.detail.value
});
},
onRegionChange(e) {
this.setData({
region: e.detail.value
});
}
});
9. <form> - 表单容器
用于统一收集表单组件的值,简化数据获取。
html
<form bindsubmit="onFormSubmit" bindreset="onFormReset">
<input name="username" placeholder="用户名" />
<input name="password" password placeholder="密码" />
<radio-group name="gender">
<radio value="male">男</radio>
<radio value="female">女</radio>
</radio-group>
<switch name="agree" value="{{true}}" />
<button form-type="submit">提交</button>
<button form-type="reset">重置</button>
</form>
javascript
Page({
onFormSubmit(e) {
const formData = e.detail.value;
console.log(formData);
// { username: '张三', password: '123', gender: 'male', agree: true }
// 提交到服务器
wx.request({
url: 'https://api.example.com/submit',
data: formData,
success: (res) => {
wx.showToast({ title: '提交成功' });
}
});
},
onFormReset(e) {
console.log('表单已重置');
}
});
互动操作组件
用于增强用户与应用之间的交互体验,涵盖手势识别、弹窗菜单、消息提示等场景。
| 组件/API | 类型 | 主要功能 | 适用场景 |
|---|---|---|---|
| 手势组件 | Skyline组件 | 拖拽、缩放、长按等手势识别 | 半屏弹窗、图片缩放、拖拽排序 |
<button> |
表单组件 | 触发交互、开放能力 | 分享、获取手机号、客服 |
| ActionSheet | 扩展组件/API | 底部弹出操作菜单 | 多选项选择、操作面板 |
| Modal | API | 模态对话框 | 重要确认、信息输入 |
| Toast/Loading | API | 轻提示/加载提示 | 操作反馈、加载状态 |
互动组件选型建议
| 场景 | 推荐方案 |
|---|---|
| 半屏弹窗+拖拽关闭 | Skyline手势组件 |
| 图片缩放/双指操作 | <scale-gesture-handler> |
| 底部操作菜单 | wx.showActionSheet |
| 重要确认弹窗 | wx.showModal |
| 简单操作反馈 | wx.showToast |
| 异步加载状态 | wx.showLoading |
| 微信分享/获取手机号 | Button open-type |
1. 手势组件(Skyline渲染引擎)
手势组件是Skyline渲染引擎内置的虚组件,直接在UI线程响应,避免了传统JS线程通信的延迟,性能更好。
| 组件名称 | 触发时机 |
|---|---|
<tap-gesture-handler> |
点击时触发 |
<double-tap-gesture-handler> |
双击时触发 |
<long-press-gesture-handler> |
长按时触发 |
<pan-gesture-handler> |
拖拽移动时触发 |
<vertical-drag-gesture-handler> |
纵向滑动时触发 |
<horizontal-drag-gesture-handler> |
横向滑动时触发 |
<scale-gesture-handler> |
多指缩放时触发 |
<force-press-gesture-handler> |
iPhone重按时触发 |
html
<!-- 拖拽手势 -->
<pan-gesture-handler worklet:ongesture="handlePan">
<view class="drag-box">拖拽我</view>
</pan-gesture-handler>
<!-- 纵向拖拽(与scroll-view协同) -->
<vertical-drag-gesture-handler
worklet:ongesture="handleVerticalDrag"
native-view="scroll-view"
>
<scroll-view scroll-y style="height: 500rpx;">
<view ="{{100}}" ="index">列表项 {{index}}</view>
</scroll-view>
</vertical-drag-gesture-handler>
手势回调中的state字段表示当前手势状态:
| 状态值 | 常量名 | 说明 |
|---|---|---|
| 0 | POSSIBLE | 手势未识别 |
| 1 | BEGIN | 手势已识别 |
| 2 | ACTIVE | 连续手势活跃中 |
| 3 | END | 手势正常结束 |
| 4 | CANCELLED | 手势被取消 |
2. 操作菜单(ActionSheet)
底部弹出的操作菜单,用于提供多个操作选项。
javascript
Page({
showActionSheet() {
wx.showActionSheet({
alertText: "请选择操作", // 提示文案
itemList: ["编辑", "删除", "分享"],
itemColor: "#000000",
success: (res) => {
console.log("点击了第" + res.tapIndex + "个按钮");
if (res.tapIndex === 0) {
// 编辑操作
} else if (res.tapIndex === 1) {
// 删除操作
}
},
fail: (error) => {
console.log("调用失败", error);
}
});
}
});
3. 模态对话框(Modal)
用于需要用户确认的重要操作。
| 属性 | 类型 | 说明 |
|---|---|---|
title |
String | 对话框标题 |
content |
String | 对话框内容 |
showCancel |
Boolean | 是否显示取消按钮 |
cancelText |
String | 取消按钮文字 |
confirmText |
String | 确认按钮文字 |
editable |
Boolean | 是否显示输入框 |
placeholderText |
String | 输入框提示文字 |
javascript
Page({
showConfirm() {
wx.showModal({
title: "温馨提示",
content: "是否确认删除该条记录?",
showCancel: true,
cancelText: "取消",
cancelColor: "#999",
confirmText: "确认",
confirmColor: "#fa2c19",
success: (res) => {
if (res.confirm) {
// 用户点击确认
console.log("确认删除");
} else if (res.cancel) {
// 用户点击取消
console.log("取消删除");
}
}
});
},
// 带输入框的模态框(基础库2.17.1+)
showPrompt() {
wx.showModal({
title: "输入昵称",
editable: true,
placeholderText: "请输入新昵称",
success: (res) => {
if (res.confirm && res.content) {
console.log("输入内容:", res.content);
}
}
});
}
});
4. 轻提示(Toast)
自动消失的提示信息,适合操作结果反馈。
javascript
Page({
showSuccess() {
wx.showToast({
title: "保存成功",
icon: "success", // success/error/loading/none
duration: 2000,
mask: true // 防止背景被点击
});
},
showError() {
wx.showToast({
title: "操作失败",
icon: "error",
duration: 2000
});
},
// 手动隐藏
hideToast() {
wx.hideToast();
}
});
5. 加载提示(Loading)
需要手动关闭的加载提示,适合异步操作。
javascript
Page({
async loadData() {
// 显示加载中
wx.showLoading({
title: "加载中...",
mask: true
});
try {
// 模拟异步请求
const res = await this.fetchData();
// 处理数据...
} catch (error) {
wx.showToast({ title: "加载失败", icon: "error" });
} finally {
// 手动关闭loading
wx.hideLoading();
}
}
});
6. Button开放能力
Button组件的open-type属性可调用微信开放能力
html
<!-- 获取用户信息 -->
<button open-type="getUserInfo" bindgetuserinfo="onGetUserInfo">
获取用户信息
</button>
<!-- 获取手机号(需后端配合) -->
<button open-type="getPhoneNumber" bindgetphonenumber="onGetPhoneNumber">
获取手机号
</button>
<!-- 分享给朋友 -->
<button open-type="share">分享</button>
<!-- 打开客服会话 -->
<button open-type="contact" bindcontact="onContact">联系客服</button>
<!-- 打开意见反馈 -->
<button open-type="feedback">意见反馈</button>
<!-- 打开APP(需APP关联) -->
<button open-type="launchApp" app-parameter="key=value">打开APP</button>
javascript
Page({
onGetUserInfo(e) {
console.log(e.detail.userInfo);
},
onGetPhoneNumber(e) {
// 新版接口返回code,需后端换取手机号
console.log(e.detail.code);
},
onShareAppMessage() {
return {
title: '分享标题',
path: '/pages/index/index'
};
}
});
页面导航组件
核心指的就是 <navigator> 组件。它主要负责在页面之间构建链接,实现用户点击后的页面跳转。简单来说,它类似于 HTML 中的 <a> 标签,但功能更丰富,能适应小程序中不同类型页面的跳转规则
1. 关键属性速查
| 属性名 | 类型 | 说明 | 最低版本 |
|---|---|---|---|
url |
String | 当前小程序内的跳转链接,路径后可以带参数-1-5。 | 1.0.0 |
open-type |
String | 跳转方式,这是最关键的属性,决定了跳转时的页面栈行为-5。 | 1.0.0 |
delta |
Number | 当 open-type="navigateBack" 时有效,表示回退的页面层数,默认为 1-5。 |
1.0.0 |
hover-class |
String | 指定点击时的样式类,默认值为 navigator-hover。可以设置为 none 来去掉点击态效果-5。 |
1.0.0 |
2. open-type 跳转方式详解
这是 <navigator> 的核心,它决定了跳转时页面栈的变化,具体有5种模式-5-6。
open-type 值 |
功能说明 | 对应API | 页面栈表现 |
|---|---|---|---|
navigate |
保留当前页面,跳转到应用内的某个页面。这是默认值 -5。 | wx.navigateTo |
新页面入栈,页面栈加1。 |
redirect |
关闭当前页面,跳转到应用内的某个页面。 | wx.redirectTo |
当前页面出栈,新页面入栈,页面栈大小不变。 |
switchTab |
跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面。 |
wx.switchTab |
清除非 tabBar 页面,切换到指定的 tabBar 页面。 |
reLaunch |
关闭所有页面,打开到应用内的某个页面。 | wx.reLaunch |
清空所有页面,新页面入栈。 |
navigateBack |
关闭当前页面,返回上一页面或多级页面。 | wx.navigateBack |
页面出栈,直到回到目标页面。 |
3. 使用注意事项
-
路径写法 :
url属性中的路径建议使用以/开头的绝对路径,这样最不容易出错。 -
页面栈限制 :小程序页面栈最多支持 10 层。使用
navigate跳转时需注意,避免页面层级过深导致无法再打开新页面。 -
样式定制 :
<navigator>组件自带点击态效果(灰色背景)。你可以通过修改.navigator-hover这个类名来全局自定义样式,或者给某个导航单独设置hover-class属性
<navigator> 组件是微信小程序页面跳转的基础,掌握它对于构建流畅的用户交互至关重要。
-
判断目标页面类型 :在写代码前,先问自己"要跳转的页面是不是 Tab 页?"。如果是,
open-type必须用switchTab;如果不是,大多数情况用默认的navigate即可。 -
传递简单参数 :直接在
url后用?拼接,格式为?key1=value1&key2=value2。参数可以在目标页面的onLoad(options)中通过options参数接收-1-9。 -
后退操作 :小程序自带返回箭头,如需自定义返回按钮,使用
open-type="navigateBack"。
除了声明式的 <navigator> 组件,小程序也支持通过 wx.navigateTo、wx.redirectTo 等 API 进行编程式导航。
媒体组件
用于在应用中展示图片、音视频、地图等富媒体内容
| 组件名 | 主要功能 | 适用场景 |
|---|---|---|
<image> |
图片展示 | 头像、商品图、轮播图、背景图 |
<video> |
视频播放 | 短视频、课程视频、直播回放 |
<camera> |
相机组件 | 拍照、扫码、人脸识别 |
<live-player> |
直播播放 | 实时直播、体育赛事 |
<live-pusher> |
直播推流 | 主播开播、视频会议 |
<audio> |
音频播放(旧版) | 背景音乐、语音播放 |
<map> |
地图组件 | 位置展示、导航、轨迹记录 |
1. <image> - 图片组件
最常用的媒体组件,支持多种图片模式和懒加载。
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
src |
String | - | 图片资源地址 |
mode |
String | scaleToFill | 图片裁剪、缩放的模式 |
lazy-load |
Boolean | false | 是否懒加载 |
show-menu-by-longpress |
Boolean | false | 长按是否显示菜单 |
webp |
Boolean | false | 是否支持WebP格式 |
binderror |
EventHandle | - | 图片加载失败触发 |
bindload |
EventHandle | - | 图片加载完成触发 |
mode 模式详解
| mode 值 | 说明 | 适用场景 |
|---|---|---|
scaleToFill |
拉伸填充,不保持比例 | 图标、背景图 |
aspectFit |
保持比例,完整显示 | 商品图、相册 |
aspectFill |
保持比例,裁剪溢出 | 头像、封面图 |
widthFix |
宽度固定,高度自适应 | 文章配图、详情图 |
heightFix |
高度固定,宽度自适应 | 横向滚动图 |
top/center/bottom |
裁剪模式 | 特定位置对齐 |
html
<!-- 头像:保持比例,居中裁剪 -->
<image class="avatar" mode="aspectFill" src="{{avatar}}" />
<!-- 商品图:完整显示,可能留白 -->
<image class="product" mode="aspectFit" src="{{productImage}}" />
<!-- 文章图:宽度固定,高度自适应 -->
<image mode="widthFix" src="{{articleImage}}" />
javascript
.avatar {
width: 80rpx;
height: 80rpx;
border-radius: 50%;
}
.product {
width: 100%;
height: 300rpx;
background-color: #f5f5f5;
}
2. <video> - 视频组件
功能强大的视频播放器,支持多种格式和播放控制。
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
src |
String | - | 视频地址 |
controls |
Boolean | true | 显示默认播放控件 |
autoplay |
Boolean | false | 自动播放 |
loop |
Boolean | false | 循环播放 |
muted |
Boolean | false | 静音播放 |
initial-time |
Number | 0 | 初始播放位置(秒) |
duration |
Number | - | 视频时长(秒) |
poster |
String | - | 视频封面图 |
object-fit |
String | contain | 填充模式(contain/fill/cover) |
show-center-play-btn |
Boolean | true | 显示中央播放按钮 |
enable-progress-gesture |
Boolean | true | 开启手势进度调节 |
show-fullscreen-btn |
Boolean | true | 显示全屏按钮 |
show-play-btn |
Boolean | true | 显示播放按钮 |
3. <camera> - 相机组件
用于调用设备摄像头,实现拍照、扫码等功能。
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
device-position |
String | back | 前置/后置摄像头(front/back) |
flash |
String | off | 闪光灯状态(auto/on/off/torch) |
frame-size |
String | medium | 帧数据尺寸(small/medium/large) |
scan-area |
Array | - | 扫码识别区域 |
binderror |
EventHandle | - | 用户不允许授权或错误 |
html
<camera
id="myCamera"
device-position="{{devicePosition}}"
flash="{{flashMode}}"
binderror="onError"
style="width: 100%; height: 600rpx;"
/>
<view class="camera-controls">
<button bindtap="toggleCamera">切换摄像头</button>
<button bindtap="toggleFlash">闪光灯: {{flashMode}}</button>
<button bindtap="takePhoto">拍照</button>
<button bindtap="scanCode">扫码</button>
</view>
<image ="{{photoPath}}" src="{{photoPath}}" mode="widthFix" />
javascript
Page({
data: {
devicePosition: 'back',
flashMode: 'off',
photoPath: ''
},
onReady() {
this.cameraContext = wx.createCameraContext();
},
toggleCamera() {
this.setData({
devicePosition: this.data.devicePosition === 'back' ? 'front' : 'back'
});
},
toggleFlash() {
const modes = ['off', 'on', 'torch'];
const currentIndex = modes.indexOf(this.data.flashMode);
const nextMode = modes[(currentIndex + 1) % modes.length];
this.setData({ flashMode: nextMode });
},
takePhoto() {
this.cameraContext.takePhoto({
quality: 'high',
success: (res) => {
this.setData({ photoPath: res.tempImagePath });
wx.saveImageToPhotosAlbum({
filePath: res.tempImagePath,
success: () => {
wx.showToast({ title: '保存成功' });
}
});
}
});
},
scanCode() {
this.cameraContext.startScanCode({
success: (res) => {
console.log('扫码结果:', res.result);
wx.showModal({
title: '扫描结果',
content: res.result
});
}
});
}
});
4. <live-player> - 直播播放组件
用于播放实时直播流,支持RTMP、HLS等协议。
使用 live-player 需要申请相应的类目权限。
html
<live-player
src="{{liveUrl}}"
mode="live"
autoplay="{{true}}"
muted="{{false}}"
bindstatechange="onStateChange"
binderror="onError"
style="width: 100%; height: 400rpx;"
/>
javascript
Page({
data: {
liveUrl: 'rtmp://example.com/live/stream'
},
onStateChange(e) {
console.log('播放状态:', e.detail.code);
// 状态码: 2001-2004 开始播放/播放中/暂停/停止
},
onError(e) {
console.error('播放错误:', e.detail);
}
});
地图组件
展示地图、标记点、路线等功能。
| 属性 | 类型 | 说明 |
|---|---|---|
latitude |
Number | 中心纬度 |
longitude |
Number | 中心经度 |
scale |
Number | 缩放级别(3-20) |
markers |
Array | 标记点数组 |
polyline |
Array | 路线数组 |
circles |
Array | 圆数组 |
controls |
Array | 控件数组 |
show-location |
Boolean | 显示带有方向的当前定位点 |
enable-zoom |
Boolean | 是否支持缩放 |
enable-scroll |
Boolean | 是否支持拖动 |
html
<map
id="myMap"
latitude="{{latitude}}"
longitude="{{longitude}}"
scale="{{scale}}"
markers="{{markers}}"
polyline="{{polyline}}"
show-location
bindmarkertap="onMarkerTap"
bindregionchange="onRegionChange"
/>
<view class="map-controls">
<button bindtap="getUserLocation">定位当前位置</button>
<button bindtap="addMarker">添加标记</button>
</view>
javascript
Page({
data: {
latitude: 39.9042, // 北京天安门
longitude: 116.4074,
scale: 14,
markers: [{
id: 1,
latitude: 39.9042,
longitude: 116.4074,
title: '天安门',
iconPath: '/images/marker.png',
width: 30,
height: 30,
callout: {
content: '天安门广场',
color: '#333',
fontSize: 14
}
}],
polyline: [{
points: [
{ latitude: 39.9042, longitude: 116.4074 },
{ latitude: 39.9142, longitude: 116.4174 }
],
color: '#07c160',
width: 4,
dottedLine: false
}]
},
onReady() {
this.mapContext = wx.createMapContext('myMap');
},
getUserLocation() {
wx.getLocation({
type: 'gcj02',
success: (res) => {
this.setData({
latitude: res.latitude,
longitude: res.longitude
});
this.mapContext.moveToLocation();
}
});
},
addMarker() {
const newMarker = {
id: Date.now(),
latitude: this.data.latitude + 0.001,
longitude: this.data.longitude + 0.001,
title: '新标记',
iconPath: '/images/marker.png'
};
this.setData({
markers: [...this.data.markers, newMarker]
});
},
onMarkerTap(e) {
const markerId = e.detail.markerId;
wx.showModal({
title: '标记点',
content: `点击了标记点ID: ${markerId}`
});
},
onRegionChange(e) {
if (e.type === 'end') {
console.log('地图移动结束');
}
}
});
地图性能
-
标记点过多时使用聚合
-
及时调用
moveToLocation定位 -
避免频繁更新 markers
画布组件
用于自由绘制图形的矩形区域,它提供了强大的绘图能力,可以满足从基础图形绘制到复杂动画、图像处理等多种场景需求
与其他大部分组件不同,<canvas> 组件本身只是一个空白的画布容器,具体的绘制工作需要通过调用相应的 API 来完成
- 两种版本,从 "旧" 到 "新"
微信小程序的 Canvas 主要经历了两个版本的演进,强烈建议新项目直接使用新版 2D Canvas。
-
旧版 Canvas(已过时):
-
通过
canvas-id来标识,使用wx.createCanvasContext(canvasId)获取绘图上下文。 -
所有绘图操作都是异步的,最后需要调用
.draw()方法才会真正将内容渲染到画布上,逻辑较复杂,性能也相对较差。
-
-
新版 Canvas 2D(推荐):
-
基础库 2.7.0 开始支持,通过
type="2d"来声明。 -
它的 API 接口与 Web 标准对齐,通过
Canvas.getContext('2d')获取的上下文与 Web 开发一致,绘图操作是同步的,性能更好,开发体验也更流畅。
-
2. 关键属性速查
在新版 Canvas 2D 中,常用属性如下:
| 属性名 | 类型 | 说明 |
|---|---|---|
type |
String | 必须 。定义画布类型,2D 绘图应设为 "2d" |
id |
String | 必须。组件的唯一标识,用于后续获取 Canvas 实例 |
disable-scroll |
Boolean | 当在 canvas 中移动且有绑定手势事件时,禁止屏幕滚动 |
bindtouchstart |
EventHandle | 手指触摸动作开始 |
bindtouchmove |
EventHandle | 手指触摸后移动 |
bindtouchend |
EventHandle | 手指触摸动作结束 |
html
<!-- canvasDemo.wxml -->
<canvas id="myCanvas" type="2d" style="width: 300px; height: 150px; border: 1px solid #ccc;"></canvas>
在页面的 onReady 生命周期中,获取节点和渲染上下文,然后进行绘制。
javascript
// canvasDemo.js
Page({
onReady() {
// 1. 通过 SelectorQuery 获取 Canvas 节点
const query = wx.createSelectorQuery();
query.select('#myCanvas')
.fields({ node: true, size: true })
.exec((res) => {
// 2. 获取 Canvas 对象和 2D 渲染上下文
const canvas = res[0].node;
const ctx = canvas.getContext('2d');
// 3. 处理设备像素比(DPI),防止图片在高分屏上模糊
const dpr = wx.getSystemInfoSync().pixelRatio;
canvas.width = res[0].width * dpr;
canvas.height = res[0].height * dpr;
ctx.scale(dpr, dpr);
// 4. 开始绘图:绘制一个红色正方形
ctx.fillStyle = 'red';
ctx.fillRect(10, 10, 50, 50);
});
}
});
代码解析:
-
wx.createSelectorQuery():用于查询页面节点。 -
canvas.getContext('2d'):获取 2D 绘图上下文,这是所有绘图操作的基础。 -
canvas.width / canvas.height:设置画布的实际像素尺寸。这与 CSS 定义的渲染尺寸(300*150px)不同,乘以dpr是为了保证绘图在高清屏上不会模糊。 -
ctx.fillRect(x, y, width, height):绘制一个实心矩形。
Canvas 可以用来实现很多复杂的功能:
-
图表绘制 :利用路径(
beginPath,lineTo)和贝塞尔曲线(bezierCurveTo)等方法,可以绘制各种统计图表,如平滑的折线图。 -
图像处理:在 canvas 上加载并绘制图片,并为其添加文字或图形水印,保护图片版权。
-
动画与游戏 :通过
canvas.requestAnimationFrame方法可以创建流畅的逐帧动画,是实现小程序游戏的基础。
使用 wxml2canvas-2d 生成海报
在实际开发中,我们经常遇到将一段复杂的UI(如包含图片、文字、头像的卡片)一键生成海报并保存或分享的需求。手动用 Canvas API 去计算每个元素的位置非常繁琐。
这时,就可以使用像 wxml2canvas-2d 这样的第三方库,它允许你像写普通页面一样,通过 WXML 和 CSS 来描述海报的样式,然后由它自动帮你绘制到 Canvas 上,极大地提高了开发效。
基本使用思路如下:
-
安装和引入 :通过 npm 安装
wxml2canvas-2d并在页面的usingComponents中注册。 -
编写 "海报模板":在 WXML 中,用一个特定类名的容器包裹起你想生成海报的内容,并像平时写样式一样,用 WXSS 定义好每个元素的样式。
-
调用方法生成图片 :在 JS 中,通过
selectComponent获取组件实例,调用其draw()和toTempFilePath()方法,就能得到一张海报图片。