【Vue3】使用二维码实现登录

学习目标:

用接口的二维码实现登录

接口文档

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">
            使用&nbsp;<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>

注意:

现在接口中没有返回图片,只有一个地址跳转到二维码界面

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值