基于 Vue3打造前台+中台通用提效解决方案(下)

news2024/11/17 13:42:48

47、通用组件 - 倒计时组件

特惠部分存在一个倒计时的功能,所以我们需要先处理对应的倒计时模块,并把它处理成一个通用组件。

那么对于倒计时模块我们又应该如何进行处理呢?
所谓倒计时,其实更多的是一个时间的处理,那么对于时间的处理,此时我们就需要使用到一个第三方的包: dayis。通过这个包我们可以处理对应的倒计时格式问题。

那么时间格式处理完成之后,接下来我们就需要处理对应的数据:
我们期望对倒计时模块,可以传递两个值:

  1. time毫秒值:表示倒计时的时长
  2. format格式:表示倒计时的展示格式

那么到这里咱们整个的倒计时功能即使就分析的差不多了,总共分成了两部分:
1.时间格式
2.数据

<template>
  <slot :data="{ timeStr, timeValue }">
    <div>
      {
  { timeStr }}
    </div>
  </slot>
</template>

<script setup>
import dayjs from 'dayjs'
import duration from 'dayjs/plugin/duration'
import 'dayjs/locale/zh-cn'
import { watch, ref, computed, onUnmounted } from 'vue'

dayjs.extend(duration)
dayjs.locale('zh-cn')
let timer = null
const props = defineProps({
  time: {
    // 倒计时时间, ms单位
    type: Number,
    required: true
  },
  format: {
    // 格式化时间
    type: String,
    default: 'HH小时mm分钟ss秒SSS'
  }
})

// 组件销毁时清理定时器
onUnmounted(() => {
  close()
})
const timeValue = ref(props.time)

// 封装格式化日期函数
const fmtTime = (milliseconds) => {
  const d = dayjs.duration(milliseconds)
  return d.format(props.format)
}

const handleSetInterval = () => {
  timer = setInterval(() => {
    if (typeof timeValue.value === 'number' && timeValue.value <= 0) {
      //完成
      close()
    } else {
      timeValue.value -= 9
    }
  }, 9)
}
const timeStr = computed(() => {
  return typeof timeValue.value === 'number' ? fmtTime(timeValue.value) : ''
})
/**
 * 关闭定时器
 */
const close = () => {
  clearInterval(timer)
}
/**
 * 开启定时器
 */
const start = () => {
  handleSetInterval()
}
/**
 * 从新设置定时器
 */
const reset = (v) => {
  const setV = v > 0 ? v : props.time
  timeValue.value = setV
}
watch(
  () => props.time,
  (v) => {
    timeValue.value = v
    close()
    start()
  },
  {
    immediate: true
  }
)

defineExpose({
  close,
  start,
  reset,
  timeStr,
  timeValue
})
</script>

48、第三方平台登录解决方案流程大解析

通常情况下我们所说的第三方登录,多指的是:通过第三方APP进行登录

那么我们这个第三方的 APP 是如何和我们自己的应用进行关联的呢?

如果大家不是很清楚,那么本小节将为你解答。
想要搞明白这个问题,那么我们首先需要搞清楚整个第三方登录的流程是如何进行的。

我们以常见app第三方登录为例:

  • 1.点击第三方登录按钮
  • 2.弹出一个小窗口,展示对应二维码
  • 3.手机打开对应的 APP进行扫码之后,会跳转到同意页面,同时浏览器端也会显示扫码成功
  • 4.手机端操作同意登录之后,会出现两种情况:
    • 1.当前用户已注册:直接登录
    • 2.当前用户未注册:执行注册功能

详细流程如下

  • 1.点击第三方登录按钮:执行 window.open方法,打开一个第三方指定的URL窗口,该地址会指向第三方登录的URL,并且由第三方提供一个对应的二维码
  • 2.弹出一个小窗口,展示对应二维码: 此处展示的二维码,即为上一步中第三方提供的二维码
  • 3.手机打开对应的 APP进行扫码之后,会跳转到同意页面,同时浏览器端也会显示扫码成功:在第三方中会一直对该页面进行轮询,配合第三方APP 来判断是否扫码成功
  • 4.手机端操作同意登录之后,会出现两种情况:在 APP 中同意之后,第三方会进行对应的跳转,跳转地址为你指定的地址,在该地址中可以获取到第三方的用户信息,该信息即为第三方登录时要获取到的关键数据
  • 5**.至此,第三方操作完成。接下来需要进行本平台的登录判定。**
    • 1.该注册指的是第三方用户是否在本平台中进行了注册。
    • 2.因为在之前的所有操作中,我们拿到的是第三方的用户信息。
    • 3.该信息可以帮助我们直接显示对用的用户名和头像,但是因为不包含关键信息(手机号、用户名、密码)所以我们无法使用该信息帮助用户直接登录
    • 4.所以我们需要判断当前用户是否在咱们自己的平台中完成了注册
      • 1.当前用户已注册:直接登录
      • 2.当前用户未注册:执行注册功能
48.1、QQ开放平台流程大解析

那么接下来我们先来处理QQ第三方登录功能。
想要对接QQ登录,那么需要使用到QQ互联平台,在该平台中:
1.注册账户

2.认证开发者

3.注册应用

48.2、QQ登录对接流程: 获取QQ用户信息

官网文档

对接QQ登录分为以下几步:

  • 1.展示QQ登录二维码
  • 2.获取用户信息
  • 3.完成跨页面数据传输
  • 4.认证是否已注册分
  • 5.完成QQ对接

展示QQ登录二维码

1、在index.html中引入QQSDK

<!-- QQ 登录 -->
    <script
      type="text/javascript"
      charset="utf-8"
      src="https://connect.qq.com/qc_jssdk.js"
      data-appid="[你的appid]"
      data-redirecturi="[你在QQ互联中配置的成功之后的回调]"
    ></script>

2、创建qq-login组件、来凤凰qq登录组件

<template>
  <div class="qq-connect-box">
    <span id="qqLoginBtn"></span>
    <svg-icon
      class="w-4 h-4 fill-zinc-200 dark:fill-zinc-300 duration-500 cursor-pointer"
      name="qq"
    ></svg-icon>
  </div>
</template>

<script setup>
import { onMounted } from 'vue'
onMounted(() => {
  QC.Login(
    {
      btnId: 'qqLoginBtn' //插入按钮的节点id
    },
    (data, ops) => {
      console.log(data, '登录成功')
    }
  )
})
</script>

image-20220922145401409

上面的图片可以得知、qqLoginBtn就是放置调起二维码按钮的地方、点击qqLoginBtn标签中的a链接、可以调起二维码;但是这样写有太丑;所以我们可以将a链接的透明度设置为0,并且置于最下方即可;css如下

<style lang="scss" scoped>
.qq-connect-box {
  position: relative;
  &:deep(#qqLoginBtn) {
    a {
      position: absolute;
      top: 0;
      right: 0;
      bottom: 0;
      left: 0;
      z-index: -1px;
      opacity: 0;
    }
  }
}
</style>

完整示例

<template>
  <div class="qq-connect-box">
    <span id="qqLoginBtn"></span>
    <svg-icon
      class="w-4 h-4 fill-zinc-200 dark:fill-zinc-300 duration-500 cursor-pointer"
      name="qq"
    ></svg-icon>
  </div>
</template>

<script setup>
import { onMounted } from 'vue'
onMounted(() => {
  // 当我们登录成功之后、会缓存起来、下次登录不需要扫码、所以我们需要注销登录、避免用户下次登录时展示上次的记录
  QC.Login(
    {
      btnId: 'qqLoginBtn' //插入按钮的节点id
    },
    (data, ops) => {
      // 扫码授权登录成功后的回到
      console.log(data, '登录成功')
      // 注销登录
      QC.Login.signOut()
      // 登录成功的回调
      // https://imooc-front.lgdsunday.club/login#access_token=4723B87EC749FA12A7247F40975D7BFB&expires_in=7776000
      // 解析地址栏地址获取token
      const accessToken = getQQAccessToken()
      // 将data中的用户昵称、和用户头像、以及accessToken发送给后台
      // TODO
    }
  )
})

const getQQAccessToken = () => {
  const hash = window.location.hash || ''
  const reg = /access_token=(.+)&expires_in/
  return hash.match(reg)[1]
}
</script>

<style lang="scss" scoped>
.qq-connect-box {
  position: relative;
  &:deep(#qqLoginBtn) {
    a {
      position: absolute;
      top: 0;
      right: 0;
      bottom: 0;
      left: 0;
      z-index: -1px;
      opacity: 0;
    }
  }
}
</style>

image-20220922151658244

注意:扫码成功重定向的地址是在小窗口打开的、并不是在原来的窗口打开、登录成功的回调也是在小窗口中回调

48.3、 QQ登录对接流程:跨页面信息传输

由于拿到扫码用户的 AccessToken 和 用户的信息(昵称、头像…) 都是在小窗口上获取到的;

这小节最要作用:就是将小窗口获取到的这些信息传递给主窗口上

想要实现跨页面信息传输,通常由两种方式:

  • 1、BroadcastChannel:允许同源的不同浏览器窗口,Tab页,frame或者iframe下的不同文档之间相互通信。但是会存在兼容性问题,实测Safari15.3 无法使用
  • 2、localStorage + window.onstorage: 通过localStorage进行同源的数据传输。用来处理BroadcastChannel不兼容的浏览器。
    那么依据以上两个API,我们实现对应的通讯模块:

utils/broadcase.js

/***
 * 向同源且不同tab标签页发送数据
 */

// BroadcastChannel的信道key; 或者localStorage的设置项的key
const BROAD_CASE_CHANNEL_KEY = 'BROAD_CASE_CHANNEL_KEY'
// BroadcastChannel实例
let broadcastChannel = null
if (window.BroadcastChanne) {
   
  // 创建BroadcastChannel实例
  broadcastChannel = new window.BroadcastChanne(BROAD_CASE_CHANNEL_KEY)
}
/**
 * 发送数据
 * @param {*} data 发送的数据包
 */
export const sendMsg = (data) => {
   
  if (broadcastChannel) {
   
    broadcastChannel.postMessage(data)
  } else {
   
    window.localStorage.setItem(BROAD_CASE_CHANNEL_KEY, JSON.stringify(data))
  }
}

/**
 * 监听数据传输
 * @returns promise对象
 */
export const listener = () => {
   
  return new Promise((resolve, reject) => {
   
    if (broadcastChannel) {
   
      broadcastChannel.onmessage = (event) => {
   
        resolve(event.data)
      }
    } else {
   
      window.onstorage = (event) 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1488727.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Socks5代理协议:原理、应用与优势

在计算机网络中&#xff0c;代理协议是一种用于转发客户端请求的机制。Socks5是其中一种广泛使用的代理协议。它主要工作在传输层和应用层之间&#xff0c;位于OSI参考模型的第五层&#xff08;会话层&#xff09;。其设计初衷是为了帮助授权用户突破防火墙限制&#xff0c;获取…

20240304-2-计算机网络

计算机网络 知识体系 Questions 1.计算机网络分层的优点和缺点 优点 各层之间是独立的&#xff1b;灵活性好&#xff1b;结构上可分割开&#xff1b;易于实现和维护&#xff1b;能促进标准化工作。 缺点&#xff1a; 降低效率&#xff1b;有些功能会在不同的层次中重复出现&…

2000-2021年全国各省市城乡平均受教育年限数据(分城镇和农村)(含原始数据+计算过程+计算结果)

2000-2021年全国各省市城乡平均受教育年限数据&#xff08;分城镇和农村&#xff09; 1、时间&#xff1a;2000-2021年 2、范围&#xff1a;全国及31省 3、来源&#xff1a;人口与就业统计年鉴 4、指标包括&#xff1a;城乡平均受教育年限 、6岁以上总人口 未上过学、…

自动化神器 Playwright 的 Web 自动化测试解决方案!

Playwright认识 3. Playwright环境搭建 Playwright简介&#xff1a; 2020年&#xff0c;微软&#xff08;Microsoft&#xff09;开源了一个名为Playwright的工具&#xff0c;与Selenium一样入门简单&#xff0c;支持多语言&#xff08;Python、Java、Node.js、.NET&#xff0…

Java8,函数式编程应用:

持续更新中&#xff1a; 函数式(Functional)接口 什么是函数式(Functional)接口 只包含一个抽象方法的接口&#xff0c;称为函数式接口。 你可以通过 Lambda 表达式来创建该接口的对象。&#xff08;若 Lambda 表达式 抛出一个受检异常(即&#xff1a;非运行时异常)&#xff0c…

Linux学习:初识Linux

目录 1. 引子&#xff1a;1.1 简述&#xff1a;操作系统1.2 学习工具 2. Linux操作系统中的一些基础概念与指令2.1 简单指令2.2 ls指令与文件2.3 cd指令与目录2.4 文件目录的新建与删除指令2.5 补充指令1&#xff1a;2.6 文件编辑与拷贝剪切2.7 文件的查看2.8 时间相关指令2.9 …

为什么TestNg会成为Java测试框架的首选?还犹豫什么,看它!

上一篇自动化测试我们大概了解了测试的目标、测试的技术选型以及搭建平台的目标及需求&#xff0c;也确定了自动化测试方案以testNg作为整个测试流程贯穿的基础支持框架&#xff0c;那么testNg究竟有什么特点&#xff1f;本篇开始我们来详细的学习testNg这个测试框架。 为什么要…

软件设计师8--输入输出技术

软件设计师8--输入输出技术 考点1&#xff1a;输入输出技术数据传输控制方式中断处理过程例题&#xff1a; 考点1&#xff1a;输入输出技术 数据传输控制方式 √ 程序控制&#xff08;查询&#xff09;方式&#xff1a;分为无条件传送和程序查询方式两种。方法简单&#xff0…

MySQL篇—执行计划之覆盖索引Using index和条件过滤Using where介绍(第三篇,总共三篇)

☘️博主介绍☘️&#xff1a; ✨又是一天没白过&#xff0c;我是奈斯&#xff0c;DBA一名✨ ✌✌️擅长Oracle、MySQL、SQLserver、Linux&#xff0c;也在积极的扩展IT方向的其他知识面✌✌️ ❣️❣️❣️大佬们都喜欢静静的看文章&#xff0c;并且也会默默的点赞收藏加关注❣…

python实现手机号归属地查询

手机上突然收到了某银行的短信提示&#xff0c;看了一下手机的位数&#xff0c;正好是11位。我一想&#xff0c;这不就是标准的手机号码吗&#xff1f;于是一个想法涌上心头——用python的库实现查询手机号码归属地查询自由。 那实现的效果如下&#xff1a; 注&#xff1a;电…

yolov7添加spd-conv注意力机制

一、spd-conv是什么&#xff1f; SPD-Conv&#xff08;Symmetric Positive Definite Convolution&#xff09;是一种新颖的卷积操作&#xff0c;它主要应用于处理对称正定矩阵&#xff08;SPD&#xff09;数据。在传统的卷积神经网络&#xff08;CNN&#xff09;中&#xff0c;…

【java数据结构】模拟二叉树的链式结构之孩子表示法,掌握背后的实现逻辑

&#x1f4e2;编程环境&#xff1a;idea &#x1f4e2;树结构&#xff0c;以及叶子&#xff0c;结点&#xff0c;度等一些名词是什么意思&#xff0c;本篇不再赘述。 【java数据结构】模拟二叉树的链式结构之孩子表示法&#xff0c;掌握背后的实现逻辑 1. 认识二叉树1.1 二叉树…

桂院校园导航 | 云上高校导航 云开发项目 二次开发教程 2.0

Gitee代码仓库&#xff1a;桂院校园导航小程序 GitHub代码仓库&#xff1a;GLU-Campus-Guide 演示视频 【校园导航小程序】2.0版本 静态/云开发项目 演示 云开发项目 2.0版本 升级日志 序号 板块 详情 1 首页 重做了首页&#xff0c;界面更加高效和美观 2 校园页 新增…

Python判断结构20个实例

基本理论基础 Python中的选择判断结构是一种编程中常用的控制结构&#xff0c;它用于根据条件的真假决定程序的执行路径。选择判断结构有多种类型&#xff0c;包括if语句、if-else语句、if-elif-else语句以及嵌套的选择结构。 首先&#xff0c;我们来介绍最常见的if语句。if语…

浅谈WPF之Binding数据校验和类型转换

在WPF开发中&#xff0c;Binding实现了数据在Source和Target之间的传递和流通&#xff0c;就像现实生活中的一条条道路&#xff0c;建立起了城镇与城镇之间的衔接&#xff0c;而数据校验和类型转换&#xff0c;就像高速公路之间的收费站和安检站。那在WPF开发中&#xff0c;如何…

引入本地图片报错:require is not defined

文章目录 问题分析1. 原始写法2. 最初的解决方案3. 尝试使用 require 引入4. 封装方法进行解析引入图片 问题 Vue3 Vite 使用本地图片报错&#xff1a;require is not defined 分析 1. 原始写法 刚开始我是这样写的&#xff0c;数据是这样定义的&#xff0c;但是数据没出…

Vue.js+SpringBoot开发高校实验室管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、研究内容2.1 实验室类型模块2.2 实验室模块2.3 实验管理模块2.4 实验设备模块2.5 实验订单模块 三、系统设计3.1 用例设计3.2 数据库设计 四、系统展示五、样例代码5.1 查询实验室设备5.2 实验放号5.3 实验预定 六、免责说明 一、摘…

2024年R2移动式压力容器充装证考试题库及R2移动式压力容器充装试题解析

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2024年R2移动式压力容器充装证考试题库及R2移动式压力容器充装试题解析是安全生产模拟考试一点通结合&#xff08;安监局&#xff09;特种作业人员操作证考试大纲和&#xff08;质检局&#xff09;特种设备作业人员上…

快速幂(求解原理+例题)

目录 反复平方法&#xff08;快速幂&#xff09;&#xff1a; 代码&#xff1a; 例题&#xff1a;快速幂求逆元 作用&#xff1a; 快速求出 的结果。 时间复杂度&#xff1a; O(logk) 如果使用一般做法&#xff0c;从1循环到k&#xff0c;时间复杂度是O(k) 反复平方法&am…

倒计时35天

小红的子序列权值和 (nowcoder.com) #include<bits/stdc.h> using namespace std; #define int long long const int N2e56; const int inf0x3f3f3f3f; const double piacos(-1.0); const int mod1e97; int c[1100][1100]; int a[1100],b[5]; void solve() {int n;cin>…