API
概述
官方提供的 api 不允许小程序的前端页面中直接调用,开发者应该是调用自己的后台,在后台中使用微信官方提供的 api ,见 [官方API介绍](基础 | 微信开放文档)
微信用户信息
登录
在页面加载的生命周期函数 onLoad 中可以立即调用 wx.login() 获取 code ,从而为后面获取用户信息做好准备,响应来的 code 只有5分钟的有效期,并且只能使用一次。详细介绍参见官方文档
onLoad() {
console.log('进入index页面的onLoad');
wx.login({
success(res){
console.log('onLoad中用户登录请求得到的响应是:', res);
if(!res) return;
const code = res.code || '';
},
fail(err){
console.log('onLoad中用户登录请求失败:', );
}
})
},
success 拿到的响应结果的模型是
{"errMsg":"login:ok","code":"sdfadsfasdfasdf"}
官方要求开发者通过 wx.login() 获得 code 后应请求开发者自己的后台服务并调用 code2Session 获取用户的 openId 和 unionId。如果多次调用 wx.login() 都没有请求 code2Session 会进入 wx.login() 的 fail 分支,并相应下面的报错信息:
errMsg:login:fail INVALID_LOGIN,access_token expired [20241121 12:59:30][wxf23fe29ef6ac21a7]
初次制作微信小程序是访客系统,参见 后台项目 的API /wxmp/getUserProfile
unionId
官方关于 unionId 的 [UnionID机制说明](UnionID 机制说明 | 微信开放文档)
在制作访 客系统 时在 自定义工具jar 中新增了实体类 com.cc.alltype.wechat.MiniGetUserProfileRes 用于接收请求用户 openId 和 unionId 的响应结果。
获取用户 openId
2024年9月21日 16:08:19 查看官网文档,现使用 wx.getUserProfile 替换之前的 wx.getUserInfo ,该接口不可在 onLoad 之类的自动执行的生命周期函数中获取用户信息,微信官方要求在用户出现点击动作时才可以获取,例如点击某个按钮的事件中。否则返回的响应是 {errMsg:"getUserProfile:fail can only be invoked by user TAP gesture."} 。要先通过 wx.login() 获取当前用户的 code ,使用该 code 通过请求开发者自己的后台服务获取微信用户 openId - 开发者后台服务中请求微信 API 获取 openId,初次实现在仓库 visitor 的方法 app.ts # getUserInfo 中。
手机号验证
分为两种:手机号快速验证组件、手机号实时验证组件。前者是获取微信用户的手机号 <button open-type="getPhoneNumber" bind:getphonenumber="getphonenumber" />
后者是每次请求时平台均会对用户选择的手机号进行验证 <button open-type="getRealtimePhoneNumber" bind:getrealtimephonenumber="getrealtimephonenumber">
注意:该获取手机号的接口针对非个人开发者,其完成了认证的小程序开放(不包含海外主体),两种验证组件需要付费使用,每个小程序账号将有1000次的体验额度。
分享到朋友圈
开启该功能要求:
- 页面允许 “发送给朋友”,即 js 页面声明函数
onShareAppMessage - 页面必须声明
onShareTimeline函数
Page({
onShareTimeline(){
return {
title: '帮我砍一刀~~~~',
query: 'id=11',
imageUrl: '/assets/floor/1.jpg'
}
},
})
转发功能
转发个人/群
要实现转发小程序给微信好友或者给微信群需要用到微信API [onShareAppMessage](Page(Object object) | 微信开放文档)
分享到朋友圈
需要调用微信API [onShareTimeline](Page(Object object) | 微信开放文档)
有两种方法可以实现转发功能
- 页面 js 文件必须声明
onShareAppMessage事件监听器,并自定义转发内容。只有定义了此事件处理函数右上角菜单才会显示转发按钮 - 通过给 button 组件设置属性
open-type='share'可以在用户点击按钮后触发Page.onShareAppMessage事件监听函数
设置下面代码后通过右上角三个点打开的菜单第一项就是分享功能
Page({
onShareAppMessage(){
return{
title: '这是个神奇的地方',
path: '/pages/cate/cate',
imageUrl: '/assets/floor/1.jpg'
}
},
}
获取微信昵称
通过下面三步获取
- 通过 form 组件中包裹 input 以及 form-type = submit 的 button 组件
- 需要将 input 组件 type 设置为 nickname ,当用户输入框输入时,键盘上方会展示微信昵称
- 给 form 绑定 submit 事件,在事件处理函数中通过事件对象获取用户昵称
注意要先点击 form 中的 input 在屏幕最下面会出现当前微信账号的昵称,选择后点击按钮,后台通过表单的提交函数获取用户昵称
<form bindsubmit="onSubmit">
<input type="nickname" name="nickname" placeholder="请输入昵称"/>
<button type="primary" plain form-type="submit">点击获取昵称</button>
</form>
onSubmit(event){
console.log(event)
console.log(event.detail.value.nickname)
}
获取头像
在按钮上使用属性 open-type="chooseAvatar" 并绑定事件 bind:chooseavatar ,后者绑定的函数代码如下,其中得到的 url 即是用户的微信头像
chooseAvatar(event){
console.log(event)
const url = event.detail.avatarUrl
if(url){
this.setData({
avatarUrl: url
})
}
}
注意此方法获取的头像地址是临时的,还要将头像图片上传到自己的服务器上再使用。此处获取微信头像的完整代码如下
<view>
<button class="btn" open-type="chooseAvatar" bind:chooseavatar="chooseAvatar">
<image class="avatar" src="{{ avatarUrl }}"/>
</button>
</view>
Page({
data:{
avatarUrl: '/assets/floor/1.jpg',
},
chooseAvatar(event){
console.log(event)
const url = event.detail.avatarUrl
if(url){
this.setData({
avatarUrl: url
})
}
}
})
本地存储
不同于 html 的是,小程序中本地存储不需要使用 JSON.stringify() 和 JSON.parse() 来兼容对象和基本类型的变量
异步CRUD:wx.setStorage() 、wx.getStorage()、wx.removeStorage()、wx.clearStorage()
同步CRUD:wx.setStorageSync()、wx.getStorageSync()、wx.removeStorageSync()、wx.clearStorageSync()
下面演示同步方式的本地存储
wx.setStorageSync('num', 11)
wx.setStorageSync('obj', {id: 1001, name: '张三'})
const num = wx.getStorageSync('num')
const obj = wx.getStorageSync('obj')
console.log(num,obj)
下面演示异步本地存储的使用方法
async handleStorage(){
wx.setStorage({
key: 'num',
data: 12
})
wx.setStorage({
key: 'obj',
data: {
id: 1002,
name: '李四'
}
})
const num = await wx.getStorage({key:'num'})
const obj = await wx.getStorage({key:'obj'})
console.log(num,obj)
},
异步API
概述
通常接受一个 object 类型的参数,例如:wx.request({})。当借口参数 Object 对象中不包含 success/fail/complete 时将默认返回 Promis,部分接口如 request,uploadFile 本身就有返回值,因此不支持 Promise 风格的调用方式,他们的 promisify 需要开发者自行封装。
网络请求
使用 wx.request() 发起网络请求,要求相关域名必须在微信公众平台进行配置,否则会在控制台报错。
封装Promise对象
下面代码封装微信官方提供的API wx.login() 方法,返回一个 Promise 对象,调用方法 wxLogin$().then(res => {...},err => {...}),前面是成功的回调,后面是失败的回调。
// 下面是 http.ts 文件的代码
const wxLogin$ = (): Promise<string> => {
return new Promise((resolve, reject) => {
wx.login({
success: res => {
if(res.code) {
resolve(res.code)// 返回微信服务器响应来的 code(用于请求openId等用户信息)
}else {
console.log('执行微信登录函数wx.login时出现异常!- http.ts#wxLogin$.success');
console.log(res);
}
},
fail: err => {// 登录失败写入后台日志表log_error
console.log('执行微信登录函数wx.login时出现异常!- http.ts#wxLogin$');
console.log(err);
reject(err);
}
})
})
}
export { wxLogin$ }
同步API
约定以 Sync 结尾,例如:wx.setStorageSync()
事件监听API
约定以on开头,例如:wx.onAppHide()
上拉加载
设置触底的高度
{ "usingComponents": {}, "onReachBottomDistance": 100 }页面添加多个 view 用于显示
<!--pages/market/market.wxml--> <text>pages/market/market.wxml</text> <view class="line"></view> <block wx:for="{{numList}}" wx:key="index"> <view>{{item}}</view> </block>为 view 制作显示样式,可以下拉越界
/* pages/market/market.wxss */ view { height: 400rpx; display: flex; align-items: center; justify-content: center; } view:nth-child(odd){ background-color: lightskyblue; } view:nth-child(even){ background-color: lightsalmon; }js控制触底后的逻辑。下面代码中使用 setTimeout 模拟获取异步数据需要耗时,能清楚的看到加载动画
// pages/market/market.ts Page({ data: { numList: [1,2,3] }, /** * 页面上拉触底事件的处理函数 */ onReachBottom() { wx.showLoading({title:'数据加载中...'}) setTimeout(() => { const lastEle = this.data.numList[this.data.numList.length-1] console.log('默认数据数组最后一个元素是:' + lastEle) let newArr = [] for(let i=0;i<3;i++){ const newEle = lastEle + i + 1 console.log('最新的元素:' + newEle) newArr.push(newEle) } console.log('新增的数组:', newArr) this.setData({ numList:[...this.data.numList,...newArr] }) console.log(this.data.numList) wx.hideLoading() }, 1500); }, })
下拉刷新
// 在页面 json 文件中做如下配置
{
"usingComponents": {},
"enablePullDownRefresh": true,// 开启下拉刷新功能,页面的配置会覆盖 app.json 中的设置
"backgroundColor": "#efefef",
"backgroundTextStyle": "light"
}
// js 文件中制作触发事件后的逻辑
onPullDownRefresh(){
console.log('....');
// 可能会出现下拉刷新的窗口不退出,要手动退出
if(this.data.numList.length === 3) wx.stopPullDownRefresh()
},
scroll-view上拉、下拉功能
<!-- wxml 代码 -->
<scroll-view
scroll-y
class="scroll-y"
lower-threshold="100"
bind:scrolltolower="getMore"
enable-back-to-top="true"
refresher-enabled
refresher-default-style="black"
refresher-background="#f7f7f8"
bind:refresherrefresh="handlPulldownRefresh"
refresher-triggered="{{expand}}"
>
<!-- wx:key的*this表示数组元素本身 -->
<view wx:for="{{numList}}" wx:key="*this">
{{item}}
</view>
</scroll-view>
<!-- scss 代码 -->
.scroll-y {
height: 100vh;
background-color: #efefef;
}
view {
height: 500rpx;
display: flex;
justify-content: center;
align-items: center;
}
view:nth-child(odd){
background-color: lightblue;
}
view:nth-child(even){
background-color: lightsalmon;
}
<!-- js代码 -->
Page({
data:{
numList: [1,2,3],
expand: false
},
handlPulldownRefresh(){
this.setData({
numList: [1,2,3],
expand: false
})
},
getMore(){
wx.showLoading({title:'数据加载中...'})
setTimeout(() => {
const lastEle = this.data.numList[this.data.numList.length-1]
console.log('默认数据数组最后一个元素是:' + lastEle)
let newArr = []
for(let i=0;i<3;i++){
const newEle = lastEle + i + 1
console.log('最新的元素:' + newEle)
newArr.push(newEle)
}
console.log('新增的数组:', newArr)
this.setData({
numList:[...this.data.numList,...newArr]
})
console.log(this.data.numList)
wx.hideLoading()
}, 1500);
},
})
