首先在项目中的 index.html 静态文件中导入js
src=qq地址
data-appid=appid
data-redirecturi=回跳地址登录成功回跳的地址
<script
src="https://connect.qq.com/qc_jssdk.js"
data-appid="100556005"
data-redirecturi="http://localhost/login/callback"></script>
测试用 appid
100556005
测试用 redirect_uri
获取最新qq地址
login.vue 页面
<div id="qqLoginBtn"></div>
onMounted(() => {
QC.Login({
btnId: "qqLoginBtn", //插入按钮的节点id
});
});
Or
<a
href="https://graph.qq.com/oauth2.0/authorize?client_id=102015968&response_type=token&scope=all&redirect_uri=http%3A%2F%2Fconsult-patients.itheima.net%2Flogin%2Fcallback"
>
<img src="@/assets/qq.svg" alt="" />
</a>
env.d.ts
/// <reference types="vite/client" />
interface Window {
_AMapSecurityConfig: {
securityJsCode: string
}
QC: {
Login: {
check(): boolean
getMe(cb: (openId: string) => void): void
}
}
}
登录成功回跳到指定页面
通过window.QC.Login.getMe((id) 获取用户id,通过用户当前的id请求登 录的接口loginByQQ,判断用户是否绑定手机号,如果绑定了手机号储存信 息,跳转页面,否则绑定手机号,让绑定手机号组件显示,然后输入信息 提交验证码绑定成功调用登录接口,跳转页面,完成第三方登录。 下面是我的代码思路,大家可以借鉴一下。
<script setup lang="ts">
import { bindMobile, loginByQQ } from "@/services/user";//调用qq绑定和注册接口
import { sendMobileCode } from "@/services/consut";//登录接口
import { onMounted, ref } from "vue";
// import { mobileRules, codeRules } from "@/utils/rules";
// import { Toast } from "vant";
import { showSuccessToast } from "vant";
import { userStore } from "@/stores/user";//本地仓库储存登录信息
import type { Users } from "@/types/Users";//登录信息类型
import { useRouter } from "vue-router";//路由
// import { useMobileCode } from "@/composable";
// 1. 进行登录
// 1.1 通过QQ的js文件提供的API获取你登录后的openId(就是登录后标识)
// 1.2 如果后台的数据库中存储了 openId + 你的账号手机号 去登录就可以成功,否则失败
// 2. 绑定手机号
// 2.1 记录两个数据 openId isBind(是否需要绑定)
// 储存qq账号生成的id
const openId = ref("");
// 组件直接的切换 是否显示手机号绑定组件
const isBind = ref(false);
// 页面加载完成执行,请求登录,判断返回信息如果登录成功
onMounted(() => {
console.log(window.QC.Login.check());
console.log(window.QC);
if (window.QC.Login.check()) {
// // 代表QQ已经登录过
window.QC.Login.getMe((id) => {
console.log("openId", id);
// 登录储存id
openId.value = id;
// // 进行登录
loginByQQ(id).then((res) => {
console.log(res);
if (res.message == "未绑定手机,请绑定手机号") {
console.log("先绑定手机号再登录");
isBind.value = true;
return;
}
// 否则登录成功
loginSuccess(res.data);
console.log("登录成功");
});
});
}
});
// 手机号
const mobile = ref("");
// 验证码
const code = ref<any>("");
// 绑定手机号
// 定义仓库
const store = userStore();
// 路由
const router = useRouter();
// 如果没有绑定手机号执行这一步
const loginSuccess = (u: Users) => {
store.setUser(u);
router.replace("/user");
showSuccessToast("登录成功");
};
// 提交绑定手机号
const bind = async () => {
// 调用手机号的接口
const res = await bindMobile({
mobile: mobile.value,
code: code.value,
openId: openId.value,
});
console.log(res.data);
// 调用分装的登录方法,传递信息 这个信息是绑定手机号完成返回的登录信息有token
loginSuccess(res.data);
};
// 发送验证码
const send = async () => {
// 调用发送验证码接口
let res = await sendMobileCode(mobile.value, "bindMobile");
console.log(res);
code.value = res.data.code;
};
</script>
<template>
<div class="login-page" v-if="isBind">
<cp-nav-bar></cp-nav-bar>
<div class="login-head">
<h3>手机绑定</h3>
</div>
<van-form autocomplete="off" ref="form" @submit="bind">
<van-field name="mobile" v-model="mobile" placeholder="请输入手机号"></van-field>
<van-field name="code" v-model="code" placeholder="请输入验证码">
<template #button>
<span class="btn-send" @click="send"> "发送验证码"</span>
</template>
</van-field>
<div class="cp-cell">
<van-button block round type="primary" native-type="submit">
立即绑定
</van-button>
</div>
</van-form>
</div>
</template>