微信小程序核心技术栈
-
- 一.WXML基础概念
- 二.数据绑定
- 三.条件渲染
- 四.列表渲染
- 五.模版系统
- 六.事件系统
- 七.WXML特殊组件
-
- [1.< block> 标签](#1.< block> 标签)
- [2.< wxs>脚本模块](#2.< wxs>脚本模块)
- 八.最佳实践与性能优化
-
- 一、WXSS基础概念
-
- 1.本质与特点
- [2. 与 Web CSS 的主要差异](#2. 与 Web CSS 的主要差异)
- 二、尺寸单位
- 三、样式导入与作用域
- 四、选择器系统
- 五、Flex布局(官方推荐方案)
- 六、WXSS高级特性
-
- 一、小程序JS运行环境
- 二、App和Page生命周期
- 三、数据绑定与更新机制
-
- 1.数据初始化
- [2.setData 深度解析](#2.setData 深度解析)
- 四、事件处理系统
WXML
一.WXML基础概念
1.本质与特点
- 基于 XML 的模板语言,类似 HTML 但具有动态绑定能力
- 与 JavaScript 逻辑层分离,通过数据驱动视图更新
- 支持模块化,可通过 复用代码片段
2.与HTML的主要差异
特性 | WXML | HTML |
---|---|---|
数据绑定 | {{ }} 语法 | 无原生支持 |
事件绑定 | bind/catch前缀 | on前缀 |
条件渲染 | wx:if/wx:for指令 | 需手动操作DOM |
模版系统 | < template> 支持数据传入 | 无标准模板方案 |
二.数据绑定
1.基础绑定
javascript
<!-- 文本插值 -->
<view>Hello {{name}}!</view>
<!-- 属性绑定 -->
<input placeholder="{{placeholderText}}" />
<!-- 表达式支持 -->
<view>{{ age + 1 }}</view>
<view>{{ flag ? 'ON' : 'OFF' }}</view>
2.高级绑定模式
javascript
<template is="user-card" data="{{...userInfo, extraData: 123}}"/>
-
对象展开绑定:
-
计算属性模拟:
javascript
// JS 中预处理数据
Page({
data: {
items: [1, 2, 3],
computedItems: [] // 通过函数计算后 setData
},
onLoad() {
this.setData({
computedItems: this.data.items.map(x => x * 2)
})
}
})
3.数据绑定限制
- 不支持函数调用:{{ Math.round(price) }} ❌
- 不支持复杂表达式:{{ value1 + value2 === 3 ? 'Y' : 'N' }} ✅
- 不支持直接修改数据:必须在 JS 中使用 setData
三.条件渲染
1.基础条件判断
javascript
<view wx:if="{{score >= 90}}">优秀</view>
<view wx:elif="{{score >= 60}}">及格</view>
<view wx:else>不及格</view>
2.多条件渲染优化
- hidden属性(适用于频繁切换的场景):
javascript
<view hidden="{{!isActive}}">内容</view>
原理:通过 display:none 控制显示
对比 wx:if :
- wx:if : 动态添加/移除DOM
3.条件渲染性能建议
场景 | 推荐方案 | 理由 |
---|---|---|
初始不显示且后续少切换 | wx:if | 减少初始 DOM 节点数 |
需要频繁切换显示状态 | hidden | 避免频繁操作 DOM |
四.列表渲染
1.基础列表
javascript
<view wx:for="{{items}}" wx:key="id">
索引:{{index}},值:{{item.name}}
</view>
2.进阶用法
- 指定索引/项变量名:
javascript
<view wx:for="{{array}}" wx:for-index="idx" wx:for-item="itm">
{{idx}}: {{itm}}
</view>
javascript
Page({
data: {
array: ['苹果', '香蕉', '橙子']
}
})
javascript
0: 苹果
1: 香蕉
2: 橙子
- 嵌套列表
javascript
<block wx:for="{{nestedArray}}">
<view wx:for="{{item.subItems}}" wx:key="*this">
{{item}}
</view>
</block>
javascript
Page({
data: {
nestedArray: [
{ subItems: ['子项1-1', '子项1-2'] },
{ subItems: ['子项2-1', '子项2-2'] }
]
}
})
javascript
子项1-1
子项1-2
子项2-1
子项2-2
- < view wx:for="{{item.subItems}}" wx:key="*this">:针对外层数组中每个元素的 subItems 属性(这是一个子数组)再次使用 wx:for 指令进行遍历。wx:key="*this" 表示把当前遍历的元素自身当作唯一键值,这样能提升渲染效率。
3.wx:key的深度解析
- 作用原理:复用已有节点,避免重新创建
- 正确写法:
javascript
<!-- 唯一 ID -->
<view wx:for="{{users}}" wx:key="id"></view>
<!-- 数组项本身(适用于基本类型数组) -->
<view wx:for="{{[1,2,3]}}" wx:key="*this"></view>
- 错误示例:
javascript
<!-- 避免使用 index 作为 key -->
<view wx:for="{{items}}" wx:key="index"></view>
五.模版系统
1.定义模版
javascript
<!-- templates/user.wxml -->
<template name="userCard">
<view class="card">
<text>姓名:{{user.name}}</text>
<text>年龄:{{user.age}}</text>
<slot></slot> <!-- 插槽支持 -->
</view>
</template>
2.使用模版
javascript
<!-- 页面中引入 -->
<import src="../../templates/user.wxml"/>
<!-- 基本使用 -->
<template is="userCard" data="{{user}}"/>
<!-- 带插槽内容 -->
<template is="userCard" data="{{user}}">
<view>这是插入的内容</view>
</template>
javascript
<template name="userCard">
<view class="user-card">
<view>姓名: {{user.name}}</view>
<view>年龄: {{user.age}}</view>
<slot></slot>
</view>
</template>
3.动态模版
javascript
<template is="{{templateName}}" data="{{...data}}"/>
javascript
Page({
data: {
templateName: 'userA',
data: { name: '张三' }
}
})
六.事件系统
1.事件分类
事件类型 | 描述 | 示例事件 |
---|---|---|
冒泡事件 | 向父节点传递 | tap、touchstart |
非冒泡事件 | 不向上传递 | input、scroll |
###2.事件绑定语法 |
javascript
<!-- 冒泡事件 -->
<view bindtap="handleTap"></view>
<!-- 阻止冒泡 -->
<view catchtap="handleTap"></view>
<!-- 互斥事件(仅一个触发) -->
<view mut-bindtap="handleTap"></view>
3.事件对象详情
javascript
Page({
handleTap(e) {
console.log(e.type) // 事件类型
console.log(e.timeStamp) // 时间戳
console.log(e.currentTarget) // 当前组件
console.log(e.target) // 触发源组件
console.log(e.detail) // 自定义数据
console.log(e.mark) // 事件标记
}
})
4.自定义数据传递
javascript
<view data-id="123" bindtap="handleTap">点击</view>
javascript
handleTap(e) {
console.log(e.currentTarget.dataset.id) // "123"
}
七.WXML特殊组件
1.< block> 标签
- 虚拟容器:不渲染真实节点,仅用于逻辑分组
- 典型场景:
< block wx:if="{{show}}">
< view>A
< view>B
< /block>
2.< wxs>脚本模块
- 作用:在WXML中处理数据(类似过滤器)
- 示例:
javascript
<wxs module="m1">
function formatPrice(price) {
return '¥' + price.toFixed(2)
}
module.exports = {
formatPrice: formatPrice
}
</wxs>
<view>{{m1.formatPrice(100)}}</view>
八.最佳实践与性能优化
1.避免过深的嵌套层级(建议不超过5层)
2.减少不必要的数据绑定:
javascript
<!-- 不推荐 -->
<view>{{ largeObject.text }}</view>
<!-- 推荐 -->
<view>{{ text }}</view>
3.使用key提升列表性能(尤其对动态排序列表)
4.复杂逻辑移至js处理,保持模版简洁
WXSS
一、WXSS基础概念
1.本质与特点
- 基于 CSS 的样式语言,扩展了响应式像素单位(rpx)
- 与 Web CSS 的兼容性:支持大多数 CSS2.1 和部分 CSS3 特性
- 样式隔离机制:默认局部作用域,避免样式污染
2. 与 Web CSS 的主要差异
特性 | WXSS | CSS |
---|---|---|
单位系统 | 新增rpx响应式单位 | 传统 px/em/rem |
样式导入 | @import 支持相对路径 | 支持多种导入方式 |
选择器支持 | 部分伪类不支持(如:hover) | 完整支持 |
全局/局部样式 | 通过文件路径自动隔离 | 需手动管理 |
二、尺寸单位
1.核心单位对比
单位 | 计算方式 | 适用场景 |
---|---|---|
rpx | 1rpx = 屏幕宽度 / 750 | 推荐 响应式布局 |
px | 1px = 物理像素 | 固定尺寸元素(如边框) |
vw/vh | 1vw = 视图宽度1% | 特殊全屏布局 |
% | 相对于父元素 | 传统百分比布局 |
2.rpx适配原理
- 基准设备:iPhone6(屏幕宽度375pt)
- 换算关系:
javascript
设备 宽度(pt) 1rpx换算
iPhone6 375 0.5px
iPhoneX 375 0.5px
iPad 768 1.024px
3.单位使用建议
javascript
/* 推荐方案 */
.container {
width: 750rpx; /* 满屏宽度 */
padding: 32rpx; /* 通用间距 */
font-size: 28rpx; /* 基础字号 */
}
/* 特殊情况使用 px */
.border {
border: 1px solid #ddd; /* 物理像素边框 */
}
三、样式导入与作用域
1.导入方式
javascript
/* 导入相对路径样式文件 */
@import "../../common/base.wxss";
/* 引入 iconfont */
@font-face {
font-family: 'iconfont';
src: url('https://at.alicdn.com/t/font_123456.woff2');
}
2.样式隔离规则
样式类型 | 作用范围 | 示例文件 |
---|---|---|
全局样式 | 所有页面 | 推荐 响应式布局 |
页面样式 | 当前页面 | pages/index/index.wxss |
组件样式 | 当前自定义组件 | components/my-component/my-component.wxss |
3.强制样式穿透
javascript
/* 方法1:添加 !important */
.text {
color: red !important;
}
/* 方法2:使用 >>> 或 ::v-deep(部分版本支持) */
.parent >>> .child {
font-size: 32rpx;
}
四、选择器系统
1.支持的选择器类型
类型 | 示例 | 说明 |
---|---|---|
类选择器 | .container | 最常用 |
ID选择器 | #header | 避免滥用 |
元素选择器 | view | 匹配组件标签 |
伪类选择器 | ::after | 仅支持部分伪类 |
属性选择器 | [data-type="1"] | 需注意性能 |
后代选择器 | .parent .child | 避免过深嵌套(≤3层) |
2.不支持的选择器
- 通配符选择器(*)
- 部分伪类(如:hover、:focus)
- 兄弟选择器(~、+)
3.选择器优先级
javascript
/* 优先级从高到低 */
!important > 行内样式 > ID > Class/属性 > 元素
五、Flex布局(官方推荐方案)
1.基本使用
javascript
.container {
display: flex;
flex-direction: row; /* 主轴方向:row | column */
justify-content: center; /* 主轴对齐 */
align-items: flex-start; /* 交叉轴对齐 */
flex-wrap: wrap; /* 换行控制 */
}
2.常用布局模式
- 水平等分布局
javascript
.item {
flex: 1; /* 等分容器 */
min-width: 0; /* 防止内容溢出 */
}
- 垂直居中
javascript
.center {
display: flex;
justify-content: center;
align-items: center;
}
3.兼容性注意
- 小程序全版本支持 Flex 布局
- 避免使用 gap 属性(需用 margin 替代)
六、WXSS高级特性
1.变量与计算
javascript
/* 定义全局变量(需配合 JS 实现) */
page {
--theme-color: #ff0000;
}
/* 使用变量 */
.text {
color: var(--theme-color);
}
2.媒体查询
javascript
/* 根据屏幕宽度适配 */
@media screen and (min-width: 768px) {
.card {
width: 80%;
}
}
3.动画支持
javascript
/* 定义关键帧 */
@keyframes slidein {
from { transform: translateX(100%); }
to { transform: translateX(0); }
}
/* 应用动画 */
.box {
animation: slidein 0.5s ease-in-out;
}
JavaScript
一、小程序JS运行环境
1.双线程架构
线程类型 | 运行环境 | 职责 |
---|---|---|
逻辑层 | JavaScriptCore / V8 | 数据处理、API调用 |
渲染层 | WebView | 页面渲染、事件响应 |
2.与浏览器JS的差异
特性 | 小程序JS | 浏览器JS |
---|---|---|
DOM/BOM | 不可用 | 完整支持 |
全局对象 | wx代替window | window |
模块系统 | CommonJs | ES Modules |
异步API | 回调/Promise混用 | 主流Promise |
二、App和Page生命周期
1.App生命周期(全局)
javascript
App({
// 生命周期
onLaunch(options) {
// 初始化完成时触发(全局一次)
console.log('场景值:', options.scene)
},
onShow(options) {
// 小程序启动或从后台进入前台
},
onHide() {
// 小程序从前台进入后台
},
// 自定义全局方法/数据
globalData: {
userInfo: null
},
// 自定义全局函数
fetchData() {
return wx.request({url: 'https://api.example.com'})
}
})
2.Page生命周期(全局)
javascript
Page({
// 生命周期
onLoad(options) {
// 页面创建时触发,接收路由参数
},
onShow() {
// 页面显示/切入前台时触发
},
onReady() {
// 页面初次渲染完成
},
onHide() {
// 页面隐藏/切入后台
},
onUnload() {
// 页面卸载时触发(跳转或关闭)
},
// 页面事件处理
onPullDownRefresh() {
// 处理下拉刷新
wx.stopPullDownRefresh()
},
onReachBottom() {
// 页面上拉触底
},
onPageScroll(e) {
// 页面滚动时触发
console.log(e.scrollTop)
},
onShareAppMessage() {
// 用户点击分享时触发
return { title: '分享标题' }
}
})
三、数据绑定与更新机制
1.数据初始化
javascript
Page({
data: {
message: 'Hello',
list: [],
user: { name: '张三', age: 20 }
}
})
2.setData 深度解析
在微信小程序里,页面的data对象用来存储页面的数据。当你需要动态更新页面上的数据,并且让界面随之刷新以反映这些数据的变化时,就可以使用this.setData方法。
基本用法
javascript
this.setData({
'message': 'New Value',
'user.age': 21 // 支持路径写法
})
高级特性
- 异步更新:多个setData会合并执行
- 性能优化:
javascript
// 错误示范(频繁更新)
for(let i=0; i<100; i++) {
this.setData({ count: i })
}
// 正确做法(批量更新)
this.setData({
count: 100,
'list[0].name': '李四'
})
四、事件处理系统
1.事件绑定与传参
javascript
<!-- WXML 中绑定 -->
<view bindtap="handleTap" data-id="123">点击</view>
<view bindinput="handleInput"></view>
- 1.通过dataset传参
可以在组件上使用**data-自定义属性来传递参数。在事件处理函数中,可以通过event.currentTarget.dataset*来获取这些参数。
javascript
<!-- pages/index/index.wxml -->
<view bindtap="handleTap" data-id="123" data-name="example">点击我</view>
javascript
// pages/index/index.js
Page({
handleTap: function(event) {
const id = event.currentTarget.dataset.id;
const name = event.currentTarget.dataset.name;
console.log('传递的 id:', id);
console.log('传递的 name:', name);
}
})
- 全局变量传参
如果需要传递复杂的数据,可以使用全局变量,在app,.js中定义全局变量,然后在页面中通过**getApp()**方法来访问和修改这些变量。
javascript
// app.js
App({
globalData: {
userInfo: null
}
})
javascript
// pages/index/index.js
Page({
onLoad: function() {
const app = getApp();
app.globalData.userInfo = {
name: 'John',
age: 25
};
},
handleTap: function() {
const app = getApp();
const userInfo = app.globalData.userInfo;
console.log('全局变量中的用户信息:', userInfo);
}
})
- 3.事件对象本事传参
有些事件对象本身会携带一些有用的信息,例如touchstart、touchmove、touchend等触摸事件,会携带触摸点的坐标信息。
javascript
<!-- pages/index/index.wxml -->
<view bindtouchstart="handleTouchStart">触摸我</view>
javascript
// pages/index/index.js
Page({
handleTouchStart: function(event) {
const touch = event.touches[0];
const x = touch.clientX;
const y = touch.clientY;
console.log('触摸点的 x 坐标:', x);
console.log('触摸点的 y 坐标:', y);
}
})
综合示例
javascript
<!-- pages/index/index.wxml -->
<view>
<view wx:for="{{list}}" wx:key="*this" bindtap="handleItemTap" data-index="{{index}}">
{{item}}
</view>
</view>
javascript
// pages/index/index.js
Page({
data: {
list: ['苹果', '香蕉', '橙子']
},
handleItemTap: function(event) {
const index = event.currentTarget.dataset.index;
const item = this.data.list[index];
console.log('点击的是第', index + 1, '项:', item);
}
})
2.事件对象结构
javascript
Page({
handleTap(e) {
console.log(e.type) // 事件类型(如 tap)
console.log(e.currentTarget) // 绑定事件的组件
console.log(e.target) // 触发事件的源组件
console.log(e.detail) // 额外信息(如 input 的值)
console.log(e.mark) // 事件标记数据
}
})
3.自定义组件
在微信小程序里,自定义事件是实现组件间通信的重要手段,可用于实现父组件向子组件、子组件向父组件,以及兄弟组件间的通信。
子组件向父组件通信
子组件可通过触发自定义事件并携带数据,将信息传递给父组件。父组件监听该自定义事件,在事件处理函数中接收数据。
子组件代码
javascript
// components/child/child.js
Component({
methods: {
sendDataToParent() {
const data = '这是来自子组件的数据';
// 触发自定义事件,并传递数据
this.triggerEvent('customEvent', { data });
}
}
})
javascript
<!-- components/child/child.wxml -->
<button bindtap="sendDataToParent">向父组件发送数据</button>
父组件代码
javascript
// pages/parent/parent.js
Page({
handleCustomEvent(e) {
const receivedData = e.detail.data;
console.log('接收到子组件的数据:', receivedData);
}
})
javascript
<!-- pages/parent/parent.wxml -->
<child bind:customEvent="handleCustomEvent"></child>
父组件向子组件通信
子组件代码
javascript
// components/child/child.js
Component({
properties: {
parentData: {
type: String,
value: ''
}
},
attached() {
console.log('接收到父组件的数据:', this.data.parentData);
}
})
javascript
<!-- components/child/child.wxml -->
<view>父组件传递的数据: {{parentData}}</view>
父组件代码
javascript
// pages/parent/parent.js
Page({
data: {
dataToChild: '这是来自父组件的数据'
}
})
javascript
<!-- pages/parent/parent.wxml -->
<child parent-data="{{dataToChild}}"></child>
兄弟组件间通信
兄弟组件间通信可借助共同的父组件作为中间桥梁。一个兄弟组件触发自定义事件将数据传递给父组件,父组件再将数据传递给另一个兄弟组件。
组件A代码
javascript
// components/componentA/componentA.js
Component({
methods: {
sendDataToParent() {
const data = '这是来自组件A的数据';
this.triggerEvent('customEvent', { data });
}
}
})
javascript
<!-- components/componentA/componentA.wxml -->
<button bindtap="sendDataToParent">向父组件发送数据</button>
组件B代码
javascript
// components/componentB/componentB.js
Component({
properties: {
siblingData: {
type: String,
value: ''
}
},
attached() {
console.log('接收到兄弟组件的数据:', this.data.siblingData);
}
})
javascript
<!-- components/componentB/componentB.wxml -->
<view>兄弟组件传递的数据: {{siblingData}}</view>
父组件代码
javascript
// pages/parent/parent.js
Page({
data: {
dataToComponentB: ''
},
handleCustomEvent(e) {
const receivedData = e.detail.data;
this.setData({
dataToComponentB: receivedData
});
}
})
javascript
<!-- pages/parent/parent.wxml -->
<componentA bind:customEvent="handleCustomEvent"></componentA>
<componentB sibling-data="{{dataToComponentB}}"></componentB>
组件化开发
一、组件基础概念
1.组件vs页面
特性 | 组件 | 页面 |
---|---|---|
配置文件 | 需声明 "component": true | 无需特殊声明 |
初始化方式 | Component() | Page() |
作用域 | 样式/数据隔离 | 全局样式可影响 |
用途 | 回调/功能复用 | 业务主视图 |
2.组件文件结构
javascript
components/
├─ my-component/
├─ my-component.js # 组件逻辑
├─ my-component.json # 组件配置
├─ my-component.wxml # 组件模板
├─ my-component.wxss # 组件样式
二、组件创建全流程
1.配置组件
javascript
// my-component.json
{
"component": true,
//"usingComponents":这是一个对象,用于声明当前组件所使用的其他自定义组件。在这个对象里,键是自定义组件在模板中使用的标签名,值是自定义组件的路径。
"usingComponents": {
//"child-comp": "../child/child":这一配置表示在当前组件里,能够使用名为child-comp的自定义组件,该组件的路径是../child/child。
"child-comp": "../child/child" # 嵌套组件声明
}
}
父组件
javascript
//parent.json
{
"component": true,
"usingComponents": {
"child-comp": "../child/child"
}
}
//parent.wxml
<view>
这是父组件
<child-comp></child-comp>
</view>
//parent.js
Component({
properties: {
// 父组件的属性
},
methods: {
// 父组件的方法
}
})
子组件
javascript
//child.json
{
"component": true
}
//child.wxml
```javascript
<view>这是子组件</view>
//child.js
Component({
properties: {
// 子组件的属性
},
methods: {
// 子组件的方法
}
})
### 2.组件构造函数
```javascript
// my-component.js
Component({
// 组件属性定义(对外接口)
properties: {
title: {
type: String,
value: '默认标题',
observer(newVal, oldVal) {
// 属性变化监听
}
}
},
// 组件内部数据
data: {
count: 0
},
// 生命周期
lifetimes: {
attached() {
console.log('组件实例进入页面节点树')
},
detached() {
console.log('组件实例被移除')
}
},
// 页面生命周期(所在页面的生命周期)
pageLifetimes: {
show() { /* 页面显示 */ },
hide() { /* 页面隐藏 */ }
},
// 方法
methods: {
handleTap() {
this.setData({ count: this.data.count + 1 })
this.triggerEvent('countchange', { value: this.data.count })
}
}
})
三、组件通信机制
1.父 → 子通信
方式一:Properties 传递
javascript
<!-- 父组件 WXML -->
<my-component title="自定义标题" count="{{parentCount}}"/>
方式二:通过 selectComponent 获取实例
javascript
// 父组件 JS
this.selectComponent('#my-comp').setData({ count: 10 })
2. 子 → 父通信
javascript
// 子组件触发自定义事件
this.triggerEvent('eventname', {
detail: { /* 数据 */ },
bubbles: false, // 是否冒泡
composed: false // 是否跨越组件边界
})
// 父组件监听
<my-component bind:eventname="handleEvent"/>
3. 兄弟组件通信
方案一:通过父组件中转
javascript
// 子组件A触发事件 → 父组件 → 子组件B
this.triggerEvent('update', {data: 1})
// 父组件 WXML
<comp-a bind:update="handleUpdate"/>
<comp-b id="comp-b"/>
// 父组件 JS
handleUpdate(e) {
this.selectComponent('#comp-b').setData(e.detail)
}
方案二:使用全局事件总线
javascript
// app.js 中定义
App({
eventBus: {
emit(event, data) { /*...*/ },
on(event, callback) { /*...*/ }
}
})
// 组件中使用
getApp().eventBus.emit('update', {data: 1})
四、组件高级特性
1. 插槽系统(Slot)
基础用法
javascript
<!-- 组件模板 -->
<view class="container">
<slot></slot>
</view>
<!-- 使用组件 -->
<my-component>
<view>插入的内容</view>
</my-component>
具名插槽
javascript
<!-- 组件模板 -->
<slot name="header"></slot>
<slot name="footer"></slot>
<!-- 使用组件 -->
<my-component>
<view slot="header">头部</view>
<view slot="footer">底部</view>
</my-component>
2.样式隔离配置
javascript
Component({
options: {
styleIsolation: 'isolated' // 可选值:
// isolated - 完全隔离
// apply-shared - 父影响子
// shared - 相互影响
}
})
3.外部样式类
javascript
// 组件 JS
Component({
externalClasses: ['custom-class'] // 接受外部样式类
})
<!-- 组件 WXML -->
<view class="custom-class">内容</view>
<!-- 使用组件 -->
<my-component custom-class="red-text"/>
动态组件实现
javascript
<!-- 动态加载组件 -->
<component is="{{componentName}}"/>
<!-- 配合 wx:if -->
<view wx:if="{{type === 'A'}}">
<comp-a/>
</view>
<view wx:else>
<comp-b/>
</view>
API体系
一、API 基础架构
1. 调用方式
调用形式 | 示例 | 特点 |
---|---|---|
同步 API | wx.setStorageSync(key, data) | 立即返回结果,命名包含 Sync |
异步 API(回调) | wx.request({ success(){} }) | 通过回调函数处理结果 |
异步 API(Promise) | wx.request().then() | 需自行封装或使用云开发 SDK |
2.运行环境限制
- 部分 API 需声明权限:在 app.json 中配置
javascript
{
"permission": {
"scope.userLocation": {
"desc": "获取位置信息"
}
}
}
- 安全域名限制:网络请求必须配置合法域名(开发阶段可关闭校验)
二、核心 API 分类详解
1. 网络请求
基础请求
javascript
wx.request({
url: 'https://api.example.com',
method: 'POST',
data: { key: 'value' },
header: { 'Content-Type': 'application/json' },
success(res) {
console.log(res.statusCode, res.data)
},
fail(err) {
console.error(err)
}
})
高级特性
- 文件上传:
javascript
wx.uploadFile({
url: 'https://upload.example.com',
filePath: tempFilePaths[0],
name: 'file',
success(res) {
console.log(res.data)
}
})
- WebSocket
javascript
const socket = wx.connectSocket({
url: 'wss://echo.websocket.org'
})
socket.onMessage(msg => console.log(msg))
2.数据缓存
操作类型 | 同步方法 | 异步方法 |
---|---|---|
存储 | wx.setStorageSync | wx.setStorage |
读取 | wx.getStorageSync | wx.getStorage |
删除 | wx.removeStorageSync | wx.removeStorage |
清空 | wx.clearStorageSync | wx.clearStorage |
javascript
// 敏感数据建议加密存储
const crypto = require('./crypto-utils')
wx.setStorageSync('token', crypto.encrypt(rawToken))
3.界面交互
弹窗系列
javascript
// 显示加载框
wx.showLoading({ title: '加载中' })
setTimeout(() => wx.hideLoading(), 2000)
// 模态对话框
wx.showModal({
title: '提示',
content: '确认删除?',
success(res) {
if (res.confirm) console.log('用户确认')
}
})
导航控制
javascript
// 页面跳转(保留当前页)
wx.navigateTo({ url: '/pages/detail?id=1' })
// Tab页切换
wx.switchTab({ url: '/pages/index' })
// 返回上一页
wx.navigateBack({ delta: 1 })
4.设备能力
地理位置
javascript
wx.getLocation({
type: 'wgs84',
success(res) {
const { latitude, longitude } = res
wx.openLocation({ latitude, longitude })
}
})
扫码功能
javascript
wx.scanCode({
success(res) {
console.log('扫码结果:', res.result)
}
})
5.媒体处理
图片处理
javascript
// 选择图片
wx.chooseImage({
count: 1,
sizeType: ['compressed'],
success(res) {
wx.previewImage({ urls: res.tempFilePaths })
}
})
录音功能
javascript
const recorderManager = wx.getRecorderManager()
recorderManager.onStart(() => console.log('录音开始'))
recorderManager.start({ format: 'mp3' })
6.开放接口
用户信息
javascript
wx.getUserProfile({
desc: '用于完善会员资料',
success(res) {
console.log(res.userInfo)
}
})
微信支付
javascript
wx.requestPayment({
timeStamp: '',
nonceStr: '',
package: '',
signType: 'MD5',
paySign: '',
success(res) { /* 支付成功 */ }
})
三、API 高级用法
1. Promise 化封装
javascript
// 通用封装方法
const promisify = (api) => (options) =>
new Promise((resolve, reject) => {
api({
...options,
success: resolve,
fail: reject
})
})
// 使用示例
const request = promisify(wx.request)
request({ url: 'https://api.example.com' })
.then(res => console.log(res.data))
2. 并发请求控制
javascript
// 使用 Promise.all
Promise.all([
promisify(wx.request)({ url: '/api/user' }),
promisify(wx.request)({ url: '/api/goods' })
]).then(([userRes, goodsRes]) => {
console.log(userRes, goodsRes)
})
3. 自定义拦截器
javascript
// 请求拦截示例
const originalRequest = wx.request
wx.request = function(options) {
// 添加全局 header
options.header = {
...options.header,
'X-Token': wx.getStorageSync('token')
}
return originalRequest(options)
}