最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

使用H5實(shí)現(xiàn)短信驗(yàn)證碼一鍵登錄功能

  發(fā)布時(shí)間:2023-09-19 11:56:17   作者:蝸牛大哥   我要評(píng)論
使用uniapp開發(fā)打包H5及PC和小程序,H5端實(shí)現(xiàn)登錄需求一開始是接入阿里云的手機(jī)號(hào)一鍵登錄服務(wù),但是H5的一鍵登錄功能需要關(guān)閉WiFi開啟數(shù)據(jù)才有效,所以換為了四位短信驗(yàn)證碼的方式進(jìn)行登錄,此文記錄如何實(shí)現(xiàn)及期間遇到的問(wèn)題

一、技術(shù)棧

uniapp+vue3+javascript

二、實(shí)現(xiàn)的效果

全部代碼可見(jiàn):https://github.com/zzm319/study-summarize.git(分支為code-login)。

1、進(jìn)入頁(yè)面第一個(gè)輸入框自動(dòng)聚焦

2、輸入后下一個(gè)輸入框自動(dòng)聚焦

3、點(diǎn)擊輸入?yún)^(qū)域自動(dòng)聚焦到無(wú)值的第一個(gè)輸入框(當(dāng)前一個(gè)輸入框無(wú)值時(shí)后一個(gè)輸入框無(wú)法聚焦 )

4、可以復(fù)制粘貼填充也可以短信驗(yàn)證碼一鍵登錄

5、監(jiān)聽鍵盤的刪除鍵(Backspace)刪除輸入的驗(yàn)證碼

三、實(shí)現(xiàn)邏輯及代碼

1、HTML部分:

利用循環(huán)渲染4個(gè)輸入框,第一個(gè)輸入框可輸入最大長(zhǎng)度無(wú)值時(shí)為4(為了復(fù)制和驗(yàn)證碼填充賦值),有值時(shí)最大可輸入長(zhǎng)度為1。

<template>
    <view class="content">
        <view class="code-area">
            <view class="propmt">已發(fā)送4位驗(yàn)證碼至 +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)進(jìn)入頁(yè)面第一個(gè)輸入框自動(dòng)聚焦:

onMounted(() => {
 ? ?// #ifdef H5
 ? ?// 處理聚焦第一個(gè)輸入框
 ? ?document.querySelectorAll('.uni-input-input')[0].focus();
 ? ?// #endif
})

2. 輸入后下一個(gè)輸入框自動(dòng)聚焦,主要是給輸入框監(jiān)聽輸入事件,判斷是否有值,有值就自動(dòng)聚焦下一個(gè)輸入框:

// 監(jiān)聽輸入輸入框 自動(dòng)聚焦到下一個(gè)輸入框
const onInput = (e, index) => {
 ? ?// index < 3 ,如果是第4格,不觸發(fā)光標(biāo)移動(dòng)至下一個(gè)輸入框。
 ? ?if (inputbox[index].labelValue && index < 3) {
 ? ? ? ?nextTick(() => {
 ? ? ? ? ? ?document.querySelectorAll('.uni-input-input')[index + 1].focus()
 ? ? ?  })
 ?  }
}

3)點(diǎn)擊輸入?yún)^(qū)域自動(dòng)聚焦到無(wú)值的第一個(gè)輸入框(當(dāng)前一個(gè)輸入框無(wú)值時(shí)后一個(gè)輸入框無(wú)法聚焦 ),主要是給輸入框區(qū)域判定一個(gè)點(diǎn)擊事件,判斷當(dāng)前哪個(gè)輸入框無(wú)值則聚焦:

// 點(diǎn)擊輸入?yún)^(qū)域 自動(dòng)聚焦到空的輸入框
const handleFocus = () => {
 ? ?if (focusIndex.value === 4) {
 ? ? ? ?document.querySelectorAll('.uni-input-input')[3].focus();
 ? ? ? ?return;
 ?  }
 ? ?document.querySelectorAll('.uni-input-input')[focusIndex.value].focus();
}

4)監(jiān)聽粘貼事件賦值給每個(gè)輸入框,主要是利用給第一個(gè)輸入框賦值后,然后給剩下的三個(gè)輸入框重新賦值(短信驗(yàn)證碼填充同理):

// 監(jiān)聽輸入?yún)^(qū)域的粘貼事件
 ? ?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('');
 ? ? ?  }
 ?  })
// 監(jiān)聽第一個(gè)輸入框的值:為了處理粘貼和短信自動(dòng)填充時(shí)賦值和聚焦
watch(() => inputbox[0].labelValue, (val) => {
 ? ?if (val) {
 ? ? ? ?// 處理輸入的時(shí)候限制輸入長(zhǎng)度
 ? ? ? ?isMaxLength.value = false;
 ?  }
 ? ?nextTick(() => {
 ? ? ? ?if (val && val.length >= 2) {
 ? ? ? ? ? ?val.split('').forEach((element, index) => {
 ? ? ? ? ? ? ? ?inputbox[index].labelValue = element;
 ? ? ? ? ?  });
 ? ? ?  }
?
 ? ? ? ?setTimeout(() => {
 ? ? ? ? ? ?// 加個(gè)定時(shí)器 避免粘貼兩次
 ? ? ? ? ? ?handleFocus();
 ? ? ?  })
 ?  })
})

注意的是,二次粘貼時(shí)需要先重置第一個(gè)輸入框的最大可輸入長(zhǎng)度:

watch(() => inputCodeValue.value, async (val) => {
 ? ?if (!val) {
 ? ? ? ?// 處理四位輸入框?yàn)榭諘r(shí)再次復(fù)制粘貼
 ? ? ? ?isMaxLength.value = true;
 ?  }
?
 ? ?if (val.length === 4) {
 ? ? ? ?// 四位輸入框的值已填滿 做登錄等邏輯操作
 ? ? ? ?console.log('to login')
 ?  }
})

5)監(jiān)聽鍵盤的刪除鍵(Backspace)刪除輸入的驗(yàn)證碼:

// 監(jiān)聽鍵盤上的刪除按鍵(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);
?
// 四位短信驗(yàn)證碼
const inputCodeValue = computed(() => inputbox.reduce((pre, item) => pre + item.labelValue, ''))
?
// 驗(yàn)證碼的長(zhǎng)度
const focusIndex = computed(() => inputCodeValue.value.length)
?
// 監(jiān)聽鍵盤上的刪除按鍵(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
 ? ?// 處理聚焦第一個(gè)輸入框
 ? ?document.querySelectorAll('.uni-input-input')[0].focus()
?
 ? ?document.addEventListener('keydown', handleListenDelete)
?
 ? ?// 監(jiān)聽輸入?yún)^(qū)域的粘貼事件
 ? ?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
})
?
// 監(jiān)聽第一個(gè)輸入框的值:為了處理粘貼和短信自動(dòng)填充時(shí)賦值和聚焦
watch(() => inputbox[0].labelValue, (val) => {
 ? ?if (val) {
 ? ? ? ?// 處理輸入的時(shí)候限制輸入長(zhǎng)度
 ? ? ? ?isMaxLength.value = false;
 ?  }
 ? ?nextTick(() => {
 ? ? ? ?if (val && val.length >= 2) {
 ? ? ? ? ? ?val.split('').forEach((element, index) => {
 ? ? ? ? ? ? ? ?inputbox[index].labelValue = element;
 ? ? ? ? ?  });
 ? ? ?  }
?
 ? ? ? ?setTimeout(() => {
 ? ? ? ? ? ?// 加個(gè)定時(shí)器 避免粘貼兩次
 ? ? ? ? ? ?handleFocus();
 ? ? ?  })
 ?  })
})
?
watch(() => inputCodeValue.value, async (val) => {
 ? ?if (!val) {
 ? ? ? ?// 處理四位輸入框?yàn)榭諘r(shí)再次復(fù)制粘貼
 ? ? ? ?isMaxLength.value = true;
 ?  }
?
 ? ?if (val.length === 4) {
 ? ? ? ?// 四位輸入框的值已填滿 做登錄等邏輯操作
 ? ? ? ?console.log('to login')
 ?  }
})
?
// 點(diǎn)擊輸入?yún)^(qū)域 自動(dòng)聚焦到空的輸入框
const handleFocus = () => {
 ? ?if (focusIndex.value === 4) {
 ? ? ? ?document.querySelectorAll('.uni-input-input')[3].focus();
 ? ? ? ?return;
 ?  }
 ? ?document.querySelectorAll('.uni-input-input')[focusIndex.value].focus();
}
?
// 監(jiān)聽輸入輸入框 自動(dòng)聚焦到下一個(gè)輸入框
const onInput = (e, index) => {
 ? ?// index < 3 ,如果是第4格,不觸發(fā)光標(biāo)移動(dòng)至下一個(gè)輸入框。
 ? ?if (inputbox[index].labelValue && index < 3) {
 ? ? ? ?nextTick(() => {
 ? ? ? ? ? ?document.querySelectorAll('.uni-input-input')[index + 1].focus()
 ? ? ?  })
 ?  }
}
?
?
onBeforeUnmount(() => {
 ? ?document.removeEventListener('keydown', handleListenDelete);
})
?
</script>

四、遇到的問(wèn)題

1、聚焦實(shí)現(xiàn)

由于uniapp使用input是通過(guò)封裝原生input標(biāo)簽實(shí)現(xiàn)的,使用ref獲取input dom節(jié)點(diǎn)的方式,不能調(diào)用focus方法實(shí)現(xiàn)聚焦,所以采用原生的獲取dom方法實(shí)現(xiàn):

document.querySelectorAll('.uni-input-input')[focusIndex.value].focus();

2、循環(huán)渲染input的方法,當(dāng)某個(gè)輸入框的值改變其它輸入框也跟著改變 原因是我fill()了一個(gè)對(duì)象,這種方式相當(dāng)于四個(gè)輸入框的值都是同一個(gè)對(duì)象。

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

3、在做點(diǎn)擊輸入?yún)^(qū)域,讓焦點(diǎn)自動(dòng)聚焦到無(wú)值的第一個(gè)輸入框時(shí),發(fā)現(xiàn)點(diǎn)擊輸入框不能實(shí)現(xiàn),點(diǎn)擊輸入框之間的間隔可以實(shí)現(xiàn)。 原因:我給每個(gè)輸入框設(shè)置了diabled屬性,讓其在上一個(gè)輸入框有值時(shí)才能使用。

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

4、ios的safari瀏覽器中,驗(yàn)證碼填充背景顏色會(huì)為黃色: (ps:網(wǎng)上有很多種方法:改變背景色,改變陰影填充等,本人試了都不能實(shí)現(xiàn),下面的方法在iphone14 ios版本為16.1.1中親測(cè)有效)

// 處理去掉safari瀏覽器填充短信驗(yàn)證碼背景色
/deep/ .uni-input-input {
 ? ? ? ? ? ?-webkit-text-fill-color: #262C33;
 ? ? ? ? ? ?transition: background-color 5000s ease-out 0.5s;
 ? ? ?  }

以上就是使用H5實(shí)現(xiàn)短信驗(yàn)證碼一鍵登錄功能的詳細(xì)內(nèi)容,更多關(guān)于H5實(shí)現(xiàn)短信驗(yàn)證碼一鍵登錄的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • H5項(xiàng)目怎么打包成APP

    開發(fā)uni-app的編輯器HBuilderX可以將H5項(xiàng)目打包成APP,相信很多小伙伴還不知道這個(gè)功能,下面將介紹下如何將H5打包成APP,感興趣的朋友一起看看吧
    2023-04-03
  • 移動(dòng)端H5實(shí)現(xiàn)拍照功能的兩種方法

    本文將介紹移動(dòng)端H5實(shí)現(xiàn)拍照功能的兩種方法:使用HTML5的input標(biāo)簽和使用第三方插件,幫助讀者更好地理解和掌握移動(dòng)端H5拍照功能的實(shí)現(xiàn),感興趣的可以了解一下
    2023-03-30
  • 短視頻滑動(dòng)播放在 H5 下的實(shí)現(xiàn)方式

    短視頻已經(jīng)無(wú)數(shù)不在了,但是主體還是使用 app 來(lái)承載的,本文講述 H5 如何實(shí)現(xiàn) app 的視頻滑動(dòng)體驗(yàn),本文對(duì)實(shí)現(xiàn)過(guò)程中踩到的坑做一個(gè)總結(jié),結(jié)合示例代碼給大家介紹的非常詳
    2023-01-05
  • HTML5頁(yè)面打開微信小程序功能實(shí)現(xiàn)

    這篇文章主要介紹了HTML5頁(yè)面打開微信小程序功能,本文通過(guò)示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-09-20
  • 如何用H5實(shí)現(xiàn)好玩的2048小游戲

    相信大多數(shù)讀者都玩過(guò)一款小游戲 2048,本文主要介紹了如何用H5實(shí)現(xiàn)好玩的2048小游戲,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需
    2022-07-18
  • h5頁(yè)面背景圖很長(zhǎng)要有滾動(dòng)條滑動(dòng)效果的實(shí)現(xiàn)

    這篇文章主要介紹了h5頁(yè)面背景圖很長(zhǎng)要有滾動(dòng)條滑動(dòng)效果的實(shí)現(xiàn),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-01-27
  • 詳解如何解決H5開發(fā)使用wx.hideMenuItems無(wú)效果不生效

    這篇文章主要介紹了詳解如何解決H5開發(fā)使用wx.hideMenuItems無(wú)效果不生效,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下
    2021-01-20
  • 關(guān)于webview適配H5上傳照片或者視頻文件的方法

    這篇文章主要介紹了關(guān)于webview適配H5上傳照片或者視頻文件的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小
    2020-11-04
  • app內(nèi)嵌H5 webview 本地緩存問(wèn)題的解決

    這篇文章主要介紹了app內(nèi)嵌H5 webview 本地緩存問(wèn)題的解決,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一
    2020-10-19
  • h5封裝下拉刷新

    這篇文章主要介紹了h5封裝下拉刷新,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-08-25

最新評(píng)論

牙克石市| 洪洞县| 富蕴县| 元谋县| 文登市| 图们市| 楚雄市| 惠来县| 五河县| 江都市| 龙泉市| 宝清县| 英德市| 阿拉尔市| 大庆市| 寿阳县| 扶风县| 石门县| 崇义县| 龙井市| 鄂伦春自治旗| 靖安县| 清涧县| 沂水县| 黄山市| 博白县| 深州市| 岳阳县| 永康市| 太原市| 昌江| 裕民县| 施甸县| 楚雄市| 嘉鱼县| 沭阳县| 宁化县| 确山县| 高唐县| 柏乡县| 双流县|