在 uni-app + Vue3 中调用微信 JSSDK 原生接口的详细方法
一、前置条件
-
环境准备
- uni-app 版本 ≥ 3.0
- Vue 版本 ≥ 3.2
- 已引入微信 JSSDK(在
index.html
中) - 已完成微信公众号配置(AppID、安全域名)
-
JSSDK 初始化
- 确保在调用接口前已完成 JSSDK 配置
- 配置中需包含要使用的接口名称(
jsApiList
)
二、调用微信原生接口的通用步骤
- 初始化 JSSDK
- 在
wx.ready
回调中调用接口 - 处理成功/失败回调
// 1. 初始化 JSSDK
wx.config({
debug: false, // 生产环境关闭调试
appId: 'YOUR_APPID',
timestamp: 123456789, // 时间戳
nonceStr: 'abcdefg', // 随机字符串
signature: '...', // 签名
jsApiList: [
'getLocation', // 地理位置
'scanQRCode', // 扫一扫
'chooseImage', // 选择图片
'updateAppMessageShareData', // 分享给朋友
// 其他需要使用的接口
]
});
// 2. 在 ready 回调中调用接口
wx.ready(() => {
// 调用具体接口
wx.getLocation({
type: 'wgs84',
success: (res) => {
// 3. 处理成功回调
console.log('地理位置:', res);
},
fail: (err) => {
// 处理失败回调
console.error('获取位置失败:', err);
}
});
});
三、在 Vue3 中封装 JSSDK 服务
推荐创建一个可复用的服务模块:
// services/wx.js
import { ref, onMounted, onUnmounted } from 'vue';
import axios from 'axios';
// 缓存配置状态
const isConfigured = ref(false);
let readyCallback = null;
// 获取签名配置
async function getSignature(url) {
try {
const response = await axios.get('/api/wx/signature', {
params: { url }
});
return response.data;
} catch (error) {
console.error('获取微信签名失败:', error);
return null;
}
}
// 初始化 JSSDK
async function initJssdk(jsApiList = []) {
// 避免重复初始化
if (isConfigured.value) return true;
// 获取当前 URL(不含 hash)
const url = window.location.href.split('#')[0];
// 获取签名配置
const config = await getSignature(url);
if (!config) return false;
return new Promise((resolve, reject) => {
wx.config({
debug: false,
appId: config.appId,
timestamp: config.timestamp,
nonceStr: config.nonceStr,
signature: config.signature,
jsApiList: [
'checkJsApi', // 检查接口可用性
...jsApiList // 用户自定义接口
]
});
wx.ready(() => {
isConfigured.value = true;
if (readyCallback) readyCallback();
resolve(true);
});
wx.error((res) => {
console.error('微信 JSSDK 配置失败:', res);
reject(res);
});
});
}
// 检查接口可用性
function checkJsApi(apiList) {
return new Promise((resolve, reject) => {
wx.checkJsApi({
jsApiList: apiList,
success: (res) => {
resolve(res.checkResult);
},
fail: (err) => {
reject(err);
}
});
});
}
// 组合式函数:在组件中使用
function useWxApi(jsApiList = []) {
// 初始化 JSSDK
onMounted(async () => {
try {
await initJssdk(jsApiList);
} catch (error) {
console.error('初始化微信 JSSDK 失败:', error);
}
});
// 调用接口的通用方法
const callWxApi = (apiName, options = {}) => {
return new Promise((resolve, reject) => {
if (!isConfigured.value) {
reject(new Error('JSSDK 未初始化'));
return;
}
wx[apiName]({
...options,
success: (res) => resolve(res),
fail: (err) => reject(err)
});
});
};
return {
isConfigured,
callWxApi,
checkJsApi
};
}
export default {
initJssdk,
checkJsApi,
useWxApi
};
四、常用接口调用示例
1. 获取地理位置
<template>
<view>
<button @click="getLocation">获取位置</button>
<text v-if="location">
纬度: {{ location.latitude }}, 经度: {{ location.longitude }}
</text>
</view>
</template>
<script setup>
import { ref } from 'vue';
import wxService from '@/services/wx';
// 注入 JSSDK 服务,指定需要的接口
const { callWxApi } = wxService.useWxApi(['getLocation']);
const location = ref(null);
const error = ref(null);
const getLocation = async () => {
try {
const res = await callWxApi('getLocation', {
type: 'wgs84', // 默认为wgs84的gps坐标,可改为'gcj02'
success: (res) => {
location.value = {
latitude: res.latitude,
longitude: res.longitude,
speed: res.speed,
accuracy: res.accuracy
};
}
});
console.log('位置信息:', res);
} catch (err) {
error.value = err;
console.error('获取位置失败:', err);
}
};
</script>
2. 扫一扫功能
<template>
<view>
<button @click="scanCode">扫一扫</button>
<text v-if="scanResult">扫描结果: {{ scanResult }}</text>
</view>
</template>
<script setup>
import { ref } from 'vue';
import wxService from '@/services/wx';
const { callWxApi } = wxService.useWxApi(['scanQRCode']);
const scanResult = ref('');
const scanCode = async () => {
try {
const res = await callWxApi('scanQRCode', {
needResult: 1, // 1: 返回结果,0: 微信处理结果
scanType: ['qrCode', 'barCode'], // 二维码或条形码
});
scanResult.value = res.resultStr;
} catch (err) {
console.error('扫描失败:', err);
}
};
</script>
3. 拍照/选择图片
<template>
<view>
<button @click="chooseImage">选择图片</button>
<view v-for="(img, index) in images" :key="index">
<image :src="img" mode="aspectFit" />
</view>
</view>
</template>
<script setup>
import { ref } from 'vue';
import wxService from '@/services/wx';
const { callWxApi } = wxService.useWxApi(['chooseImage']);
const images = ref([]);
const chooseImage = async () => {
try {
const res = await callWxApi('chooseImage', {
count: 9, // 最多选择9张
sizeType: ['original', 'compressed'], // 原图或压缩图
sourceType: ['album', 'camera'], // 相册或相机
});
images.value = res.localIds; // 本地图片ID
// 上传图片到微信服务器(可选)
for (const localId of res.localIds) {
try {
const uploadRes = await callWxApi('uploadImage', {
localId,
isShowProgressTips: 1
});
console.log('上传成功,serverId:', uploadRes.serverId);
// 可将 serverId 发送到自己的服务器
} catch (uploadErr) {
console.error('上传失败:', uploadErr);
}
}
} catch (err) {
console.error('选择图片失败:', err);
}
};
</script>
4. 分享功能
<template>
<view>
<button @click="setShareConfig">设置分享</button>
</view>
</template>
<script setup>
import wxService from '@/services/wx';
const { callWxApi } = wxService.useWxApi([
'updateAppMessageShareData', // 分享给朋友
'updateTimelineShareData' // 分享到朋友圈
]);
const setShareConfig = async () => {
try {
// 设置分享给朋友
await callWxApi('updateAppMessageShareData', {
title: '分享标题',
desc: '分享描述',
link: 'https://yourdomain.com/share',
imgUrl: 'https://yourdomain.com/logo.png',
success: () => {
console.log('设置好友分享成功');
}
});
// 设置分享到朋友圈
await callWxApi('updateTimelineShareData', {
title: '分享标题',
link: 'https://yourdomain.com/share',
imgUrl: 'https://yourdomain.com/logo.png',
success: () => {
console.log('设置朋友圈分享成功');
}
});
} catch (err) {
console.error('设置分享失败:', err);
}
};
</script>
五、高级用法
1. 批量检查接口可用性
const checkApiAvailability = async () => {
try {
const result = await wxService.checkJsApi([
'getLocation',
'scanQRCode',
'chooseImage'
]);
console.log('接口可用性:', result);
// result 格式: { getLocation: true, scanQRCode: true, ... }
} catch (err) {
console.error('检查接口失败:', err);
}
};
2. 自定义组合式函数
// composables/useWxLocation.js
import { ref, onMounted } from 'vue';
import wxService from '@/services/wx';
export function useWxLocation() {
const location = ref(null);
const isLoading = ref(false);
const error = ref(null);
const { callWxApi } = wxService.useWxApi(['getLocation']);
const getLocation = async (options = {}) => {
isLoading.value = true;
error.value = null;
try {
const res = await callWxApi('getLocation', {
type: 'wgs84',
...options
});
location.value = {
latitude: res.latitude,
longitude: res.longitude,
speed: res.speed,
accuracy: res.accuracy
};
} catch (err) {
error.value = err;
} finally {
isLoading.value = false;
}
};
// 组件挂载时自动获取位置(可选)
onMounted(() => {
getLocation();
});
return {
location,
isLoading,
error,
getLocation
};
}
在组件中使用:
<template>
<view>
<button @click="getLocation">刷新位置</button>
<view v-if="isLoading">加载中...</view>
<view v-else-if="error">错误: {{ error.errMsg }}</view>
<view v-else-if="location">
纬度: {{ location.latitude }}, 经度: {{ location.longitude }}
</view>
</view>
</template>
<script setup>
import { useWxLocation } from '@/composables/useWxLocation';
const { location, isLoading, error, getLocation } = useWxLocation();
</script>
六、注意事项
-
URL 一致性
- 签名计算的 URL 必须与当前页面 URL 完全一致(不含 hash)
- 单页应用路由变化时需重新获取签名
-
错误处理
- 使用 try/catch 捕获接口调用错误
- 常见错误:签名错误、权限不足、接口未配置
-
接口限制
- 部分接口需要用户授权(如地理位置)
- 某些接口有调用频率限制(如上传图片)
-
版本兼容
- 检查微信客户端版本是否支持所需接口
- 使用
checkJsApi
验证接口可用性
-
生产环境优化
- 关闭
debug: true
- 缓存签名配置(有效期 7200 秒)
- 错误日志上报
- 关闭
通过以上方法,您可以在 uni-app + Vue3 项目中优雅地调用微信 JSSDK 提供的各种原生接口,实现丰富的微信生态功能。