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