当前位置: 代码网 > it编程>网页制作>html5 > 使用H5实现短信验证码一键登录功能

使用H5实现短信验证码一键登录功能

2023年09月19日 html5 我要评论
使用H5实现短信验证码一键登录功能使用uniapp开发打包H5及PC和小程序,H5端实现登录需求一开始是接入阿里云的手机号一键登录服务,但是H5的一键登录功能需要关闭WiFi开启数据才有效,所以换为了四位短信验证码的方式进... 23-09-19

一、技术栈

uniapp+vue3+javascript

二、实现的效果

全部代码可见:https://github.com/zzm319/study-summarize.git(分支为code-login)。

1、进入页面第一个输入框自动聚焦

2、输入后下一个输入框自动聚焦

3、点击输入区域自动聚焦到无值的第一个输入框(当前一个输入框无值时后一个输入框无法聚焦 )

4、可以复制粘贴填充也可以短信验证码一键登录

5、监听键盘的删除键(backspace)删除输入的验证码

三、实现逻辑及代码

1、html部分:

利用循环渲染4个输入框,第一个输入框可输入最大长度无值时为4(为了复制和验证码填充赋值),有值时最大可输入长度为1。

<template>
    <view class="content">
        <view class="code-area">
            <view class="propmt">已发送4位验证码至 +86 {{ phonenum }}</view>
            <view class="code-input" @click="handlefocus">
                <input v-for="(item, index) in inputbox" type="number" :key="index" v-model="item.labelvalue"
                    class="input-code" :maxlength="index === 0 && ismaxlength ? 4 : 1" @input="oninput($event, index)" />
            </view>
        </view>
    </view>
</template>

2、javascript部分:

1)进入页面第一个输入框自动聚焦:

onmounted(() => {
    // #ifdef h5
    // 处理聚焦第一个输入框
    document.queryselectorall('.uni-input-input')[0].focus();
    // #endif
})

2. 输入后下一个输入框自动聚焦,主要是给输入框监听输入事件,判断是否有值,有值就自动聚焦下一个输入框:

// 监听输入输入框 自动聚焦到下一个输入框
const oninput = (e, index) => {
    // index < 3 ,如果是第4格,不触发光标移动至下一个输入框。
    if (inputbox[index].labelvalue && index < 3) {
        nexttick(() => {
            document.queryselectorall('.uni-input-input')[index + 1].focus()
        })
    }
}

3)点击输入区域自动聚焦到无值的第一个输入框(当前一个输入框无值时后一个输入框无法聚焦 ),主要是给输入框区域判定一个点击事件,判断当前哪个输入框无值则聚焦:

// 点击输入区域 自动聚焦到空的输入框
const handlefocus = () => {
    if (focusindex.value === 4) {
        document.queryselectorall('.uni-input-input')[3].focus();
        return;
    }
    document.queryselectorall('.uni-input-input')[focusindex.value].focus();
}

4)监听粘贴事件赋值给每个输入框,主要是利用给第一个输入框赋值后,然后给剩下的三个输入框重新赋值(短信验证码填充同理):

// 监听输入区域的粘贴事件
    document.queryselector('.code-input').addeventlistener('paste', (event) => {
        const pastetext = (event.clipboarddata || window.clipboarddata).getdata("text");
        const arr = pastetext.split('').filter(item => /\d/.test(number(item)));
        const newarr = arr.slice(0, 4).map(item => number(item));
        if (newarr.length) {
            inputbox[0].labelvalue = newarr.join('');
        }
    })
// 监听第一个输入框的值:为了处理粘贴和短信自动填充时赋值和聚焦
watch(() => inputbox[0].labelvalue, (val) => {
    if (val) {
        // 处理输入的时候限制输入长度
        ismaxlength.value = false;
    }
    nexttick(() => {
        if (val && val.length >= 2) {
            val.split('').foreach((element, index) => {
                inputbox[index].labelvalue = element;
            });
        }
​
        settimeout(() => {
            // 加个定时器 避免粘贴两次
            handlefocus();
        })
    })
})

注意的是,二次粘贴时需要先重置第一个输入框的最大可输入长度:

watch(() => inputcodevalue.value, async (val) => {
    if (!val) {
        // 处理四位输入框为空时再次复制粘贴
        ismaxlength.value = true;
    }
​
    if (val.length === 4) {
        // 四位输入框的值已填满 做登录等逻辑操作
        console.log('to login')
    }
})

5)监听键盘的删除键(backspace)删除输入的验证码:

// 监听键盘上的删除按键(backspace)
const handlelistendelete = (e) => {
    if (e.keycode === 8 && focusindex.value > 0) {
        inputbox[focusindex.value - 1].labelvalue = '';
        document.queryselectorall('.uni-input-input')[focusindex.value].focus();
    }
}
​
onmounted(() => {
document.addeventlistener('keydown', handlelistendelete)
})

3、完整javascript代码:

<script setup>
import { ref, reactive, watch, onbeforeunmount, nexttick, onmounted, computed } from 'vue';
​
let inputbox = reactive(new array(4).fill().map((item, index) => ({ id: index, labelvalue: '' })));
let phonenum = ref('');
let ismaxlength = ref(true);
​
// 四位短信验证码
const inputcodevalue = computed(() => inputbox.reduce((pre, item) => pre + item.labelvalue, ''))
​
// 验证码的长度
const focusindex = computed(() => inputcodevalue.value.length)
​
// 监听键盘上的删除按键(backspace)
const handlelistendelete = (e) => {
    if (e.keycode === 8 && focusindex.value > 0) {
        inputbox[focusindex.value - 1].labelvalue = '';
        document.queryselectorall('.uni-input-input')[focusindex.value].focus();
    }
}
​
​
onmounted(() => {
    // #ifdef h5
    // 处理聚焦第一个输入框
    document.queryselectorall('.uni-input-input')[0].focus()
​
    document.addeventlistener('keydown', handlelistendelete)
​
    // 监听输入区域的粘贴事件
    document.queryselector('.code-input').addeventlistener('paste', (event) => {
        const pastetext = (event.clipboarddata || window.clipboarddata).getdata("text");
        const arr = pastetext.split('').filter(item => /\d/.test(number(item)));
        const newarr = arr.slice(0, 4).map(item => number(item));
        if (newarr.length) {
            inputbox[0].labelvalue = newarr.join('');
        }
    })
    // #endif
})
​
// 监听第一个输入框的值:为了处理粘贴和短信自动填充时赋值和聚焦
watch(() => inputbox[0].labelvalue, (val) => {
    if (val) {
        // 处理输入的时候限制输入长度
        ismaxlength.value = false;
    }
    nexttick(() => {
        if (val && val.length >= 2) {
            val.split('').foreach((element, index) => {
                inputbox[index].labelvalue = element;
            });
        }
​
        settimeout(() => {
            // 加个定时器 避免粘贴两次
            handlefocus();
        })
    })
})
​
watch(() => inputcodevalue.value, async (val) => {
    if (!val) {
        // 处理四位输入框为空时再次复制粘贴
        ismaxlength.value = true;
    }
​
    if (val.length === 4) {
        // 四位输入框的值已填满 做登录等逻辑操作
        console.log('to login')
    }
})
​
// 点击输入区域 自动聚焦到空的输入框
const handlefocus = () => {
    if (focusindex.value === 4) {
        document.queryselectorall('.uni-input-input')[3].focus();
        return;
    }
    document.queryselectorall('.uni-input-input')[focusindex.value].focus();
}
​
// 监听输入输入框 自动聚焦到下一个输入框
const oninput = (e, index) => {
    // index < 3 ,如果是第4格,不触发光标移动至下一个输入框。
    if (inputbox[index].labelvalue && index < 3) {
        nexttick(() => {
            document.queryselectorall('.uni-input-input')[index + 1].focus()
        })
    }
}
​
​
onbeforeunmount(() => {
    document.removeeventlistener('keydown', handlelistendelete);
})
​
</script>

四、遇到的问题

1、聚焦实现

由于uniapp使用input是通过封装原生input标签实现的,使用ref获取input dom节点的方式,不能调用focus方法实现聚焦,所以采用原生的获取dom方法实现:

document.queryselectorall('.uni-input-input')[focusindex.value].focus();

2、循环渲染input的方法,当某个输入框的值改变其它输入框也跟着改变 原因是我fill()了一个对象,这种方式相当于四个输入框的值都是同一个对象。

let inputbox = reactive(new array(4).fill({ id: index, labelvalue: '' });

3、在做点击输入区域,让焦点自动聚焦到无值的第一个输入框时,发现点击输入框不能实现,点击输入框之间的间隔可以实现。 原因:我给每个输入框设置了diabled属性,让其在上一个输入框有值时才能使用。

:disabled="item.labelvalue || (index >= 1 && !inputbox[index - 1].labelvalue)"

4、ios的safari浏览器中,验证码填充背景颜色会为黄色: (ps:网上有很多种方法:改变背景色,改变阴影填充等,本人试了都不能实现,下面的方法在iphone14 ios版本为16.1.1中亲测有效)

// 处理去掉safari浏览器填充短信验证码背景色
/deep/ .uni-input-input {
            -webkit-text-fill-color: #262c33;
            transition: background-color 5000s ease-out 0.5s;
        }

以上就是使用h5实现短信验证码一键登录功能的详细内容,更多关于h5实现短信验证码一键登录的资料请关注代码网其它相关文章!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com