官方:地址
标题
出现的问题
1692861955468
解决后效果
1692861665687
正常使用(按照官网的流程进行使用)
fn.js
该文件就是钉钉官网的js文件,我下载到了本地
js文件下载地址
javascript
!function(e){var t={};function r(n){if(t[n])return t[n].exports;var o=t[n]={i:n,l:!1,exports:{}};return e[n].call(o.exports,o,o.exports,r),o.l=!0,o.exports}r.m=e,r.c=t,r.d=function(e,t,n){r.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},r.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)r.d(n,o,function(t){return e[t]}.bind(null,o));return n},r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,"a",t),t},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r.p="",r(r.s=1382)}({1382:function(e,t){var r=function(e,t){var r=e.match(new RegExp("[?&]"+t+"=([^&]+)"));return r?r[1]:null};window.DTFrameLogin=function(e,t,n,o){var i,u=e.id&&document.getElementById(e.id)||null,c=document.createElement("iframe");t.client_id&&t.redirect_uri&&t.response_type&&t.scope?u?(u.innerHTML="",u.appendChild(c),c&&c.contentWindow&&c.contentWindow.postMessage&&window.addEventListener?(c.src="https://"+((i=t).isPre?"pre-login":"login")+".dingtalk.com/oauth2/auth?iframe=true&redirect_uri="+i.redirect_uri+"&response_type="+i.response_type+"&client_id="+i.client_id+"&scope="+i.scope+(i.prompt?"&prompt="+i.prompt:"")+(i.state?"&state="+i.state:"")+(i.org_type?"&org_type="+i.org_type:"")+(i.corpId?"&corpId="+i.corpId:"")+(i.exclusiveLogin?"&exclusiveLogin="+i.exclusiveLogin:"")+(i.exclusiveCorpId?"&exclusiveCorpId="+i.exclusiveCorpId:""),c.width=""+(e.width||300),c.height=""+(e.height||300),c.frameBorder="0",c.scrolling="no",window.addEventListener("message",(function(e){var t=e.data,i=e.origin;if(/login\.dingtalk\.com/.test(i)&&t)if(t.success&&t.redirectUrl){var u=t.redirectUrl,c=r(u,"authCode")||"",d=r(u,"state")||"",s=r(u,"error")||"";c?n&&n({redirectUrl:u,authCode:c,state:d}):o&&o(s)}else o&&o(t.errorMsg)}))):o&&o("Browser not support")):o&&o("Element not found"):o&&o("Missing parameters")}}});
util.js
这个文件就是按照钉钉文档的流程编写的代码
javascript
//钉钉js文件地址
import './fn.js'
//跳转地址,需要在钉钉后台提前配置好,暂时未用到
const url = location.origin + '/#/'
export const BASE_URL = encodeURIComponent(url);
const appid_default = 'xxxxxx' //填写自己的钉钉应用id
const state_default = 'PC'
const fn = () => {
console.log('默认的回调');
}
//INIT_DINDING 生成钉钉二维码 传递两个参数
//参数一,html标签id,该标签用来渲染二维码
//参数二,回调,在扫码完成后,进行的操作
export const INIT_DINDING = (id = "qr_code_div", callback = fn) => {
const demo = new window.DTFrameLogin(
{
id,
width: 300,//二维码宽度
height: 300,//二维码高度
},
{
client_id: appid_default,
redirect_uri: BASE_URL,
client_id: appid_default,
scope: 'openid',
response_type: 'code',
state: state_default,
prompt: 'consent',
},
(loginResult) => {
// const { redirectUrl, authCode, state } = loginResult;
//loginResult字段说明____________________________
//redirectUrl 重定向的地址
//authCode !!!很重要,这个就是钉钉返回的唯一标识
//state 我上面写的PC,因此这个值就是PC,用来以后区别pc和app
// 这里可以直接进行重定向
// window.location.href = redirectUrl;
// 也可以在不跳转页面的情况下,使用code进行授权
//------------------------------------------触发回调------------------------------------------------------------------------------------------------------------
callback && callback(loginResult)
return
},
)
}
edit.vue
封装出现二维码的组件
html
<template>
<div>
<div class="qr_code_div" ref="qrCodeDiv" id="qr_code_div"></div>
</div>
</template>
<script>
//看准你自己的文件地址---------------
import { INIT_DINDING, SET_MESSAGE } from "./util.js";
export default {
data() {
return {};
},
mounted() {
INIT_DINDING("qr_code_div",function () {
console.log("this__________________这是扫码的回调");
// fn=null
});
},
created() {},
methods: {},
beforeDestroy(){
}
};
</script>
<style lang="scss" scoped>
.qr_code_div {
width: 300px;
height: 300px;
margin: 0 auto;
}
</style>
app.vue
使用组件
html
<template>
<div>
<button @click='blg = !blg'>{{blg}}</button>
<edit v-if="blg"></edit>
</div>
</template>
<script>
import edit from './edit'
export default {
data() {
return {
blg:true
};
},
components:{
edit
},
mounted() {
},
created() {},
methods: {},
};
</script>
<style lang="scss" scoped>
</style>
```**按照上面的流程便可以正常的在h5使用钉钉的扫码组件了**
# 修改后使用(解决方式)
## **解决组件关闭后,多次开启组件会产生多个回调的bug**
在上方的edit.vue组件中进行修改
```html
<template>
<div>
<div class="qr_code_div" ref="qrCodeDiv" id="qr_code_div"></div>
</div>
</template>
<script>
import { INIT_DINDING, SET_MESSAGE } from "../utils/init";
//1、步骤一
//修改之前的匿名回调
let fn = function () {
console.log("this__________________这是扫码的回调");
//2、步骤二
//回调执行后把函数置空
fn = null;
};
export default {
data() {
return {};
},
mounted() {
//3、步骤三,传递修改后的回调
INIT_DINDING("qr_code_div", fn);
},
created() {},
methods: {},
beforeDestroy() {
//4、步骤四---组件销毁也把函数置空
fn = null;
},
};
</script>
<style lang="scss" scoped>
.qr_code_div {
width: 300px;
height: 300px;
margin: 0 auto;
}
</style>
自己的理解(路人可忽略该内容!)
查看钉钉的打包后的源码,发现是通过绑定message监听来接受回调的
其实还有另外一种,就是在message事件执行后,立即取消绑定,只让他执行一次
但是考虑到是匿名事件,并且是打包后的代码,并没有进行更改
就使用了另一种方法,也就是上诉的方法
钉钉源码
javascript
! function (e) {
var t = {};
function r(n) {
if (t[n]) return t[n].exports;
var o = t[n] = {
i: n,
l: !1,
exports: {}
};
return e[n].call(o.exports, o, o.exports, r), o.l = !0, o.exports
}
r.m = e, r.c = t, r.d = function (e, t, n) {
r.o(e, t) || Object.defineProperty(e, t, {
enumerable: !0,
get: n
})
}, r.r = function (e) {
"undefined" != typeof Symbol && Symbol.toStringTag && Object.defineProperty(e, Symbol.toStringTag, {
value: "Module"
}), Object.defineProperty(e, "__esModule", {
value: !0
})
}, r.t = function (e, t) {
if (1 & t && (e = r(e)), 8 & t) return e;
if (4 & t && "object" == typeof e && e && e.__esModule) return e;
var n = Object.create(null);
if (r.r(n), Object.defineProperty(n, "default", {
enumerable: !0,
value: e
}), 2 & t && "string" != typeof e)
for (var o in e) r.d(n, o, function (t) {
return e[t]
}.bind(null, o));
return n
}, r.n = function (e) {
var t = e && e.__esModule ? function () {
return e.default
} : function () {
return e
};
return r.d(t, "a", t), t
}, r.o = function (e, t) {
return Object.prototype.hasOwnProperty.call(e, t)
}, r.p = "", r(r.s = 1382)
}({
1382: function (e, t) {
var r = function (e, t) {
var r = e.match(new RegExp("[?&]" + t + "=([^&]+)"));
return r ? r[1] : null
};
window.DTFrameLogin = function (e, t, n, o) {
var i, u = e.id && document.getElementById(e.id) || null,
c = document.createElement("iframe");
t.client_id && t.redirect_uri && t.response_type && t.scope ? u ? (u.innerHTML = "", u.appendChild(c), c && c.contentWindow && c.contentWindow.postMessage && window.addEventListener ? (c.src = "https://" + ((i = t).isPre ? "pre-login" : "login") + ".dingtalk.com/oauth2/auth?iframe=true&redirect_uri=" + i.redirect_uri + "&response_type=" + i.response_type + "&client_id=" + i.client_id + "&scope=" + i.scope + (i.prompt ? "&prompt=" + i.prompt : "") + (i.state ? "&state=" + i.state : "") + (i.org_type ? "&org_type=" + i.org_type : "") + (i.corpId ? "&corpId=" + i.corpId : "") + (i.exclusiveLogin ? "&exclusiveLogin=" + i.exclusiveLogin : "") + (i.exclusiveCorpId ? "&exclusiveCorpId=" + i.exclusiveCorpId : ""), c.width = "" + (e.width || 300), c.height = "" + (e.height || 300), c.frameBorder = "0", c.scrolling = "no", window.addEventListener("message", (function (e) {
var t = e.data,
i = e.origin;
//这里这里-------------------------------看上面👆
if (/login\.dingtalk\.com/.test(i) && t)
if (t.success && t.redirectUrl) {
var u = t.redirectUrl,
c = r(u, "authCode") || "",
d = r(u, "state") || "",
s = r(u, "error") || "";
c ? n && n({
redirectUrl: u,
authCode: c,
state: d
}) : o && o(s)
} else o && o(t.errorMsg)
}))) : o && o("Browser not support")) : o && o("Element not found") : o && o("Missing parameters")
}
}
});