学习目标:
用接口的二维码实现登录
接口文档
https://binaryify.github.io/NeteaseCloudMusicApi/#/?id=neteasecloudmusicapi
学习内容:
1. 写api接口,接口文档中二维码登录有三个步骤,写好三个接口
/**
* 二维码登录 二维码登录涉及到 3 个接口,调用务必带上时间戳,防止缓存
* 1. 二维码 key 生成接口
*/
export function getKey(time) {
return get(`/login/qr/key?time=`+time).then((res) => {
return res;
})
}
/**
* 2. 二维码生成接口
* 此接口传入上一个接口生成的 key 可生成二维码图片的 base64 和二维码信息,
* 可使用 base64 展示图片,或者使用二维码信息内容自行使用第三方二维码生成库渲染二维码
* 必选参数: key,由第一个接口生成
* 可选参数: qrimg 传入后会额外返回二维码图片 base64 编码
*/
export function getCreateKey(key) {
return get(`/login/qr/create?key=${key}`).then((res) => {
return res;
})
}
/**
* 3. 二维码检测扫码状态接口
* 询此接口可获取二维码扫码状态,
* 800 为二维码过期,801 为等待扫码,802 为待确认,803 为授权登录成功(803 状态码下会返回 cookies)
* 必选参数: key,由第一个接口生成
*/
export function getCheckKey(key,time) {
return get(`/login/qr/check?key=${key}+&time=`+time).then((res) => {
return res;
})
}
2. 创建store仓库进行数据统一管理
import { createStore } from "vuex";
import { getKey, getCreateKey, getCheckKey,loginStatus } from "@/api/login.js";
export default createStore({
state: {
user: {
isLogin: false, //是否登录
key: "",
img: "",
imgUrl: "",
cookies: "",
unikey: "",
},
},
mutations: {
setUser(state, value) {
//修改img的值
state.user.img = value.qrimg;
state.user.imgUrl = value.qrurl;
},
setStatus(state, value) {
//修改cookie
state.user.cookies = value.cookie;
state.user.isLogin = true;
},
},
actions: {
// 获取二维码
async login(content, payload) {
//调第一个接口拿key
let result = await getKey(Date.now());
//调第二个接口拿二维码图片
let createRes = await getCreateKey(result.data.unikey);
if (createRes.code == 200) {
content.commit("setUser", createRes.data); //修改img的信息
this.check;
}
// 800为二维码过期,801为等待扫码,802为待确认,803为授权登录成功
//每三秒check一次
let check = setInterval(async () => {
let statusRes = await getCheckKey(result.data.unikey, new Date().getTime());
content.commit("setStatus", statusRes);
if (statusRes.code == 800) {
clearInterval(check);
//检查登录状态
let da = await loginStatus();
}
if (statusRes.code == 803) {
clearInterval(check);
}
}, 3000);
},
},
});
3. 在页面中调用
<template>
<div class="login-bg">
<div class="login-contain">
<div class="login-header">
<p>欢迎登录</p>
</div>
<div class="mid">
<div class="left">
<img
src="
https://p5.music.126.net/obj/wo3DlcOGw6DClTvDisK1/9643571155/525c/faac/2dc6/fe695c03c7c358ddaa4651736b26a55f.png"
alt=""
/>
</div>
<div class="right">
<div class="rightt">扫码登陆</div>
<img :src="$store.state.user.img" alt="" style="width: 170px; height: 170px" />
<div class="rightb">
使用 <a
href="https://music.163.com/#/download"
style="color: skyblue"
>网易云app</a
>
扫码登录
</div>
</div>
</div>
<div class="order-login">
<p class="order-login-line">其他登录方式</p>
<div class="order-login-box">
<div>
<a :href="$store.state.user.img">
<img
src="../assets/img/wechat-login.png"
alt=""
style="width: 45px; height: 45px"
/>
<p @click="weLogin">微信登录</p>
</a>
</div>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { onMounted, ref } from "vue";
import { useRouter } from "vue-router";
import { useStore } from "vuex";
const store = useStore();
const router = useRouter();
const weLogin = () => {};
onMounted(() => {
//等待拿出的数据
store.dispatch("login"); //传入的store方法
});
</script>
<style lang="less" scoped>
a,
li {
list-style: none;
}
a {
text-decoration: none;
color: black;
}
.mid {
padding: 30px;
display: flex;
}
.left img {
width: 125px;
height: 220px;
}
.right {
margin-left: 20px;
display: flex;
align-content: space-between;
flex-direction: column;
}
.rightt {
margin-left: 5px;
font-size: 18px;
font-weight: 500;
color: #333;
color: rgba(0, 0, 0, 0.4);
}
.rightb {
margin-left: 15px;
}
.login-bg {
position: fixed;
width: 100vw;
height: 100vh;
left: 0;
top: 0;
z-index: 100000;
// background: url("../images/login-bg.jpg") no-repeat fixed;
background: #74c3ca;
color: #ffffff;
background-size: 100% 100%;
}
.login-contain {
width: 85%;
margin: 0 auto;
}
.login-header {
padding: 5%;
}
.login-header p {
font-size: 32px;
color: #ffffff;
font-weight: bold;
text-align: center;
letter-spacing: 2px;
text-shadow: 0.1em 0.15em 0.1em #74c3ca;
}
.order-login {
padding: 5%;
}
.order-login-line {
display: block;
position: relative;
text-align: center;
font-size: 14px;
color: #ffffff;
}
.order-login-line:before,
.order-login-line:after {
content: "";
position: absolute;
top: 50%;
background: #ffffff;
width: 20%;
height: 1px;
}
.order-login-line:before {
left: 10%;
}
.order-login-line:after {
right: 10%;
}
.order-login-box {
display: flex;
width: 100%;
justify-content: center;
margin-top: 20px;
}
.order-login-box div {
flex: 1;
text-align: center;
}
.order-login-box div p {
text-align: center;
font-size: 14px;
color: #ffffff;
}
</style>
注意:
现在接口中没有返回图片,只有一个地址跳转到二维码界面