前端Vue自定义发送短信验证码弹框popup 实现剩余秒数计数 重发短信验证码

news2024/12/24 8:14:43

前端Vue自定义发送短信验证码弹框popup 实现剩余秒数计数 重发短信验证码, 请访问uni-app插件市场地址:https://ext.dcloud.net.cn/plugin?id=13207

效果图如下:

实现代码如下:

# cc-codeDialog

#### 使用方法

```使用方法

<!-- show:是否显示弹框 phone:手机号  autoCountdown:自动时间秒数 len:短信验证码长度 @closeClick:关闭弹框 @confirmClick:确认事件 -->

<cc-codeDialog :show="show" phone="1900000000" :autoCountdown="true" :len="6" @closeClick="closeCodeDialog" @confirmClick="confirmClick"></cc-codeDialog>

```

#### HTML代码实现部分

```html

<template>

<view class="content">

<button @click="showCodeDialog" style="margin-top: 39px;">发送短信验证码 </button>

<!-- show:是否显示弹框 phone:手机号  autoCountdown:自动时间秒数 len:短信验证码长度 @closeClick:关闭弹框 @confirmClick:确认弹框 -->

<cc-codeDialog :show="show" phone="1900000000" :autoCountdown="true" :len="6" @closeClick="closeCodeDialog"

@confirmClick="confirmClick"></cc-codeDialog>

</view>

</template>

<script>

export default {

data() {

return {

show: false

}

},

methods: {

showCodeDialog(item) {

this.show = true;

},

closeCodeDialog(item) {

this.show = false;

},

confirmClick(result) {

console.log("result = " + JSON.stringify(result));

this.show = false;

}

}

}

</script>

<style>

.content {

display: flex;

flex-direction: column;

background-color: aliceblue;

height: 100vh;

}

</style>

```

#### 组件实现代码

```组件实现代码

<template>

<view v-if="show" class="codedialog">

<view class="mask"></view>

<view class="dialog-view">

<text class="dialog-close" @click="closeDialog()"></text>

<view class="dialog-hd">

<view class="codedialog-maintitle">

<text>发送验证码</text>

</view>

<view v-if="phone!='' && phone !=null " class="codedialog-subtitle">

<text>已发送到手机号:{{phoneStr}}</text>

</view>

</view>

<view class="dialog-bd">

<view class="code-view">

<view v-for="(code,index) of codeAry" :key="index" class="code-item">{{code.val}}</view>

</view>

</view>

<view class="dialog-ft">

<view v-if="countdown==60" @click="resend" class="resend">重新发送</view>

<view v-if="countdown<60" class="countdown">{{countdown}}s</view>

</view>

<button style="margin-top: 20px; width: 88%;background-color: royalblue;color: white;"

@click="confirmClick">确定</button>

</view>

<view class="keyboard">

<view class="keyboard-line">

<view data-val="1" @click="bindKeyEvent" class="button-item">1</view>

<view data-val="2" @click="bindKeyEvent" class="button-item">2</view>

<view data-val="3" @click="bindKeyEvent" class="button-item">3</view>

</view>

<view class="keyboard-line">

<view data-val="4" @click="bindKeyEvent" class="button-item">4</view>

<view data-val="5" @click="bindKeyEvent" class="button-item">5</view>

<view data-val="6" @click="bindKeyEvent" class="button-item">6</view>

</view>

<view class="keyboard-line">

<view data-val="7" @click="bindKeyEvent" class="button-item">7</view>

<view data-val="8" @click="bindKeyEvent" class="button-item">8</view>

<view data-val="9" @click="bindKeyEvent" class="button-item">9</view>

</view>

<view class="keyboard-line">

<view data-val="clear" @click="bindKeyEvent" class="button-item">清空</view>

<view data-val="0" @click="bindKeyEvent" class="button-item">0</view>

<view data-val="delete" @click="bindKeyEvent" class="button-item">x</view>

</view>

</view>

</view>

</template>

<script>

export default {

props: {

show: {

type: Boolean,

default: false

},

autoCountdown: {

type: Boolean,

default: true

},

phone: {

type: String,

default: ""

},

len: {

type: Number,

default: 6

}

},

data() {

return {

codeAry: [{

"val": ""

}, {

"val": ""

}, {

"val": ""

}, {

"val": ""

},

{

"val": ""

},

{

"val": ""

}

],

currItem: 0,

countdown: 60,

cTimer: null,

callResult: {

type: 0,

code: ''

},

suspend: false

};

},

computed: {

phoneStr() {

return this.phone.substr(0, 3) + "****" + this.phone.substr(7);

}

},

watch: {

show: function() {

console.log(this.show)

if (this.show) {

if (!this.suspend) {

this.init();

}

} else {

if (!this.suspend) {

this.clearTimer();

}

this.clearCode();

}

}

},

methods: {

init: function() {

var codeAry = [];

for (var i = 0; i < this.len; i++) {

codeAry.push({

val: ""

})

}

this.codeAry = codeAry;

this.currItem = 0;

if (this.autoCountdown) {

this.startTimer();

}

},

bindKeyEvent: function(e) {

var _this = this;

var val = e.currentTarget.dataset.val;

switch (val) {

case "clear":

_this.clearCode();

break;

case "delete":

_this.deleteCode();

break;

default:

_this.inputVal(val);

break;

}

},

inputVal: function(val) {

if (this.currItem < this.len) {

this.codeAry[this.currItem].val = val;

this.currItem++;

}

if (this.currItem == this.len) {

this.execuCall(1);

}

},

clearCode: function() {

this.init();

},

deleteCode: function() {

if (this.currItem > 0) {

this.codeAry[this.currItem - 1].val = "";

this.currItem--;

}

},

closeDialog: function() {

this.execuCall(-1);

this.$emit("closeClick");

},

startTimer: function() {

var _this = this;

if (_this.cTimer == null) {

_this.cTimer = setInterval(function() {

_this.countdown--;

if (_this.countdown == 0) {

_this.clearTimer();

}

}, 1000)

}

},

clearTimer: function() {

var _this = this;

clearInterval(_this.cTimer);

_this.cTimer = null;

_this.countdown = 60;

},

getCodeValue: function() {

var codeStr = "";

this.codeAry.forEach(function(code) {

codeStr += code.val;

})

return codeStr;

},

execuCall: function(type) {

this.callResult.type = type;

if (type == 1) {

this.callResult.code = this.getCodeValue();

this.clearTimer();

} else {

this.suspend = true;

this.callResult.code = '';

}

this.$emit("change", this.callResult);

},

resend: function() {

var _this = this;

_this.callResult.code = '';

_this.callResult.type = 0;

// _this.callResult.resendCall = function() {

// }

_this.init();

_this.$emit("change", _this.callResult);

},

confirmClick() {

console.log("result = " + JSON.stringify(this.callResult));

if (this.callResult.code.length < 6) {

uni.showModal({

title: '温馨提示',

content: '输入短信验证码长度有误'

})

} else {

this.$emit("confirmClick", this.callResult);

}

}

}

}

</script>

<style scoped>

.button-item:active {

background: #d4d4d4;

}

.button-item+.button-item {

border-left: 0.1px solid #d4d4d4;

}

.button-item {

flex: 1;

padding: 14px 0px;

}

.keyboard-line+.keyboard-line {

border-top: 0.1px solid #d4d4d4;

}

.keyboard-line {

display: flex;

}

.keyboard {

background: #fff;

position: absolute;

z-index: 999;

width: 100%;

left: 0;

bottom: 0;

font-size: 17px;

}

.dialog-close {

color: #999;

height: 28px;

width: 28px;

font-size: 19px;

top: 5px;

left: 5px;

position: absolute;

}

.dialog-close:before {

content: "\2716";

}

.countdown {

color: #666;

font-size: 16px;

}

.resend {

color: #007aff;

font-size: 16px;

}

.dialog-ft {

margin-top: 10px;

}

.code-view {

display: flex;

text-align: center;

margin: 0 auto;

border-collapse: separate;

border-spacing: 10px 5px;

}

.code-item+.code-item {

margin-left: 5px;

}

.code-item {

flex: 1;

border-bottom: 1px solid #999;

padding-bottom: 2px;

height: 60upx;

display: flex;

align-items: center;

justify-content: center;

font-size: 30upx;

}

.dialog-bd {

margin-top: 5px;

}

.codedialog-subtitle {

margin-top: 5px;

padding: 5px 0px;

font-size: 15px;

line-height: 1.4;

word-wrap: break-word;

word-break: break-all;

color: #999;

}

.dialog-view {

position: fixed;

z-index: 999;

width: 70%;

max-width: 300px;

top: 50%;

left: 50%;

transform: translate(-50%, -120%);

background-color: #fff;

text-align: center;

border-radius: 3px;

overflow: hidden;

padding: 20px 10px;

}

.mask {

position: fixed;

z-index: 999;

top: 0;

right: 0;

left: 0;

bottom: 0;

background: rgba(0, 0, 0, .6);

}

.codedialog {

z-index: 999;

position: fixed;

width: 100%;

height: 100%;

top: 0;

left: 0;

box-sizing: border-box;

text-align: center;

}

</style>

```

 

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

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

相关文章

【uniapp】uniapp反向代理解决跨域问题

背景介绍 前段时间&#xff0c;在拿uniapp开发的时候&#xff0c;出现了跨域问题&#xff0c;按理说跨域应该由后端解决&#xff0c;但既然咱前端可以上&#xff0c;我想就上了&#xff08;顺手装个13&#xff09; 什么是跨域 出于浏览器的同源策略&#xff0c;在请求时&…

React 简单实现 v-if和v-show的元素控制效果

react中并没有直接的想模板引擎那样的命令可以直接控制元素展示 但是 我们了解了 v-if和v-show之后 还是大有文章的 我们在 项目的 src下创建 components 文件夹 创建dom.jsx 编写代码如下 import React from "react" export default class dom extends React.Comp…

Ubuntu查看显卡信息

查看显卡信息&#xff0c;终端输入 lspci | grep VGA 输出结果 0000:65:00.0 VGA compatible controller: NVIDIA Corporation Device 24b0 (rev a1) 发现是十六进制码&#xff0c;进入网址PCI Devices查询&#xff0c;输入 24b0 并点击 Jump&#xff0c;得到结果 显卡型号…

Inline Assembly 内联汇编总结

The language used for inline assembly in Solidity is called Yul. 在solidity中&#xff0c;用于写内联汇编的语言是Yul. Inline assembly is a way to access the Ethereum Virtual Machine at a low level. This bypasses several important safety features and checks …

中国信通院联合腾讯安全发布《数据安全治理与实践白皮书》

6月26日&#xff0c;由中国通信标准化协会和中国信息通信研究院联合主办的“2023大数据产业发展大会”在北京启幕&#xff0c;大会发布了多项中国信息通信研究院及相关机构在数智化领域最新研究和实践成果。 腾讯云安全总经理李滨出席了数据安全高质量发展论坛&#xff0c;分享…

【探测器】opencv显示探测器的raw图像

【探测器】opencv显示探测器的raw图像 1、背景2、代码3、下载 1、背景 对于探测器&#xff08;相对于可见光成像的相机&#xff0c;这里的探测器指的是对X光成像的相机&#xff09;。 RAW文件几乎是未经过处理而直接从CCD或CMOS上得到的信息。 RAW格式是无损格式&#xff0c;相…

剑指 Offer ! ! 34. 二叉树中和为某一值的路径

剑指 Offer 34. 二叉树中和为某一值的路径 给你二叉树的根节点 root 和一个整数目标和 targetSum &#xff0c;找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。 叶子节点 是指没有子节点的节点。 输入&#xff1a;root [5,4,8,11,null,13,4,7,2,null,null,5,1],…

京微齐力:基于H7的曼彻斯特(编码解码串口)系统

目录 前言一、关于曼彻斯特编码二、任务&实验效果三、硬件选择1、H7P20N0L176-M2H12、XC7A35TFGG484-2 四、程序设计1、顶层模块2、编码&发送模块3、解码&接收模块4、HC595驱动模块5、段选&位选模块 五、debugware 回环实验六、兼容设计七、工程获取 前言 四月…

Doris架构包含哪些技术?为什么进行技术整合?

Doris主要整合了Google Mesa(数据模型)&#xff0c;Apache Impala(MPP Query Engine)和Apache ORCFile (存储格式&#xff0c;编码和压缩)的技术。 为什么要将这三种技术整合? Mesa可以满足我们许多存储需求的需求&#xff0c;但是Mesa本身不提供SQL查询引擎。 Impala是一个…

在做debrief评论自动往上滚动和对讲自动滚动时遇到的问题

描述&#xff1a;在获取滚动高度并且给dom元素设置scrollTo属性后&#xff0c;对于第一个元素的滚动是有问题的&#xff0c;不管在top给补充高度都是无效的。 原因&#xff1a;第一个需要滚动的元素,没有进行正常滚动&#xff1a;因为vue还没有计算出来第一个元素的完整高度&a…

电子器件系列43:IGBT技术参数

以IXBH16N170为例 IGBT/三极管/MOS管的区别&#xff1f; IGBT/三极管/MOS管的区别_哔哩哔哩_bilibili 导通电阻&#xff1f; 如果器件导通&#xff0c;开始通过电流&#xff08;比如100A&#xff09;&#xff0c;那么其对应的电阻就是导通电阻&#xff0c;如果导通电阻小&am…

ONLYOFFICE 7.4版新增函数详解

ONLYOFFICE升级到7.4版本后&#xff0c;在其表格编辑器中新增了一些公式函数&#xff1a;SEQUENCE、XMATCH、EXPAND、FILTER、ARRAYTOTEXT和SORT&#xff0c;大大加强了对矩阵、数组的操作处理能力。这一组函数公式&#xff0c;在微软的Excel里面是专属于Office365和OfficeOnli…

libevent(15)bufferevent filter的过滤器及例子

一、bufferevent filter简单说明 filter之类的东西&#xff0c;相信有php框架或java springboot经验的程序员应该很熟悉&#xff0c;就是加载在输入流之前或输出流之后的一个处理器&#xff0c;用来从业务处分离开来做一些额外的事情。 &#xff08;1&#xff09;读取&#xf…

vscode配置终端默认为git bash

vscode配置终端默认为git bash 文章目录 vscode配置终端默认为git bashctrl shift p 打开设置添加 git bash 并设为默认终端 ctrl shift p 打开设置 添加 git bash 并设为默认终端 注意不要配置 git-bash.exe 的路径。 如果配置为 git-bash.exe 路径&#xff0c;则会单独打…

阿里云服务器ping不通如何解决?

阿里云服务器ping不通&#xff1f;什么原因&#xff1f;在安全组中允许【全部 ICMP(IPv4)】&#xff0c;当然阿里云服务器禁ping也是通过配置安全组的ICMP规则来实现的&#xff0c;阿里云服务器网来详细说下安全组开通ping功能教程&#xff1a; 目录 阿里云服务器ping不通的解…

Node Sass version 6.0.1 is incompatible with ^4.0.0问题解决

运行环境背景 操作系统&#xff1a;Windows 10 64位 node版本&#xff1a;v16.19.1 npm版本&#xff1a;8.19.3 解决方案 卸载当前版本的node-sass和node-loader npm uninstall node-sass npm uninstall node-loader 重新安装指定版本 npm i node-sass6.0.1 node-loade…

计算机图形学综述(一)

计算机已经成为快速、经济地生成图片的强大工具。实际上已经没有哪个领域不能从使用图形显示中获益&#xff0c;因此也就不奇怪为什么计算机图形学的应用是那么广泛。虽然早期的工程和科学上的应用必须依赖于昂贵而笨重的设备&#xff0c;但是计算机技术的发展已经将交互式计算…

sharding-jdbc分片功能学习笔记

sharding-jdbc是sharding-sphere下的一个模块&#xff0c;可以理解为增强版的jdbc&#xff0c;用于解决分库分表、读写分离问题&#xff0c;本文基于4.1.1版本进行说明数据分片功能的流程 该版本提供了如下功能 1.数据分片&#xff08;包括强制路由功能&#xff09; 2.读写分…

win10系统下安装qt5.12.0软件

一、软件下载 1、Qt开源社区下载 下载地址&#xff1a;https://download.qt.io/archive/qt/5.12/5.12.10/qt-opensource-windows-x86-5.12.10.exe 社区地址&#xff1a; Index of /archive/qt/5.12/5.12.10 2、百度网盘下载 链接&#xff1a;https://pan.baidu.com/s/1Sqi…