一、场景与需求
在企业级 H5 开发中,常需集成钉钉扫码功能(如扫描工牌、设备码、订单码等)。本文将详细介绍如何在 Vue 项目中结合 Vant UI,通过钉钉 JSAPI 实现扫码功能,并解决实际开发中的关键问题。
二、环境准备
安装钉钉 JSAPI 库
npm install dingtalk-jsapi --save
该库提供钉钉客户端的 JS 接口调用能力,支持扫码、分享、登录等功能。
三、核心代码实现
以下是完整的 Vue 组件代码,包含扫码按钮、结果展示和交互逻辑:
<template>
<div class="scan-page">
<!-- 扫码按钮 -->
<van-button
type="primary"
size="large"
@click="handleScan"
:loading="isLoading"
>
{{ isLoading ? '正在扫码...' : '点击扫码' }}
</van-button>
<!-- 扫码结果 -->
<div v-if="scanResult" class="result-container">
<van-card>
<h3>扫码结果</h3>
<p>内容:{{ scanResult }}</p>
<p>时间:{{ formatScanTime }}</p>
</van-card>
</div>
</div>
</template>
<script>
import * as dd from 'dingtalk-jsapi'; // 引入钉钉 JSAPI
import { format } from 'date-fns'; // 时间格式化工具(可选)
export default {
data() {
return {
isLoading: false, // 扫码 loading 状态
scanResult: null, // 扫码结果
scanTimestamp: null // 扫码时间戳
};
},
computed: {
formatScanTime() {
// 格式化时间(如:2023-10-01 12:30:00)
return this.scanTimestamp ? format(new Date(this.scanTimestamp), 'yyyy-MM-dd HH:mm:ss') : '--';
}
},
methods: {
async handleScan() {
// 1. 检查是否在钉钉环境
if (!this.isInDingTalk()) {
this.$toast.fail('请在钉钉客户端中打开!'); // 使用 Vant 的 Toast 提示
return;
}
// 2. 执行扫码逻辑
this.isLoading = true;
try {
const result = await this.scanWithDingTalk();
this.handleScanSuccess(result);
} catch (error) {
this.handleScanError(error);
} finally {
this.isLoading = false;
}
},
// 检查是否在钉钉环境
isInDingTalk() {
return dd.env.platform === 'dingtalk';
},
// 调用钉钉扫码 API
scanWithDingTalk() {
return new Promise((resolve, reject) => {
dd.biz.util.scan(
{
type: 'all', // 扫码类型(all: 支持二维码/条形码;qrCode: 仅二维码)
needCrop: false, // 是否开启裁剪(适用于精准扫码场景)
quality: 'high', // 扫码质量(high/normal/low)
title: '仓库扫码', // 自定义扫码界面标题(可选)
message: '请对准二维码扫描' // 自定义扫码界面提示语(可选)
},
(successResult) => resolve(successResult), // 成功回调
(error) => reject(error) // 失败回调
);
});
},
// 处理扫码成功
handleScanSuccess(result) {
this.scanResult = result.text; // 扫码内容(如文本、URL、数字等)
this.scanTimestamp = Date.now(); // 记录时间戳
this.$toast.success('扫码成功!');
console.log('扫码结果:', result);
},
// 处理扫码失败
handleScanError(error) {
console.error('扫码失败:', error);
this.$toast.fail(`扫码失败:${error.errorMessage || '未知错误'}`);
}
}
};
</script>
<style scoped>
.scan-page {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
min-height: 100vh;
background-color: #f5f5f5;
padding: 20px;
}
.result-container {
width: 100%;
max-width: 600px;
margin-top: 30px;
padding: 20px;
background-color: #fff;
border-radius: 12px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
}
</style>
四、关键功能解析
-
钉钉环境检测
通过dd.env.platform
判断当前环境:dingtalk
:钉钉客户端内notInDingTalk
:非钉钉环境,需提示用户用钉钉打开。
-
扫码 API 配置
dd.biz.util.scan
的核心参数:参数 说明 type
扫码类型,可选 all
(通用)、qrCode
(二维码)、barCode
(条形码)needCrop
是否裁剪扫码区域,默认 false
quality
扫码质量, high
适合光线较差场景title/message
自定义扫码界面文案(提升业务辨识度) -
异步处理优化
- 使用
Promise
封装钉钉的回调式 API,配合async/await
实现同步写法,避免回调嵌套。 - 通过
try/catch
统一处理成功与失败逻辑,代码结构更清晰。
- 使用
-
用户体验优化
- 添加
loading
状态防止重复点击。 - 使用 Vant 的
$toast
替代原生alert
,提示更美观且支持自动关闭。
- 添加