溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

uniapp怎么自定義驗證碼輸入框并隱藏光標

發(fā)布時間:2023-02-22 11:52:10 來源:億速云 閱讀:136 作者:iii 欄目:開發(fā)技術

這篇文章主要講解了“uniapp怎么自定義驗證碼輸入框并隱藏光標”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“uniapp怎么自定義驗證碼輸入框并隱藏光標”吧!

一. 前言

  1. 點擊輸入框喚起鍵盤,藍框就相當于input的光標,驗證碼輸入錯誤或者不符合格式要求會將字體以及邊框改成紅色提示,持續(xù)1s,然后清空數據,恢復原邊框樣式;

  2. 5位驗證碼輸入完畢,點擊頁面其他位置,隱藏鍵盤;這時如果發(fā)現驗證碼有誤,再次點擊輸入框又喚起鍵盤,也能正常刪除數字(這里其實做的時候遇到了bug,再次聚焦不能刪除錯誤數字,下文會講到)。

二. 實現思路

具體實現思路:

  • 將input標簽相對于父元素做絕對定位,與父元素左邊距設置為負的本身寬度即可(position: absolute; top: 0; left:-100%; width: 100%; height: 100%;)。

  • 動態(tài)去設置input的focus屬性。

  • input同級使用for循環(huán)去創(chuàng)建5個正方形的view標簽。

  • 給input同級創(chuàng)建的view標簽綁定點擊事件,在點擊事件方法實現中去設置input的focus屬性為true,即可彈出鍵盤。

  • 在鍵盤輸入的時候,即可觸發(fā)input屬性的一系列方法,利用v-model雙向綁定,將input輸入的值賦值給循環(huán)的view方框即可。

  • 這樣input也就不在屏幕中,但是又可以觸發(fā)input的事件。

總的來說就是,使用for循環(huán)去創(chuàng)建5個正方形的view標簽,然后創(chuàng)建一個input標簽,type=tel,最大輸入長度為5(根據需求來設置),再將input偽隱藏掉,獲取的值分別放到5個view中展示。

驗證碼失敗后利用v-model雙向綁定,清空輸入的值,增加錯誤提示文字和邊框樣式。

三. 代碼實現

父組件

<uni-popup ref="codeInputPopup" background-color="#fff" :mask-click ="false" type="center">
     <CodeInput
	  :codeLength="5"
	  :disabled="codeBtnDisabled"
	  @codeInputClose="codeInputClose"
	  @submitGoodCode="submitGoodCode"
	 />
</uni-popup>
<script>
export default {
  data() {
    return {
     	intviation_code:'', //邀請碼
		codeBtnDisabled: false //防止接口請求還未返回數據,用戶多次點擊
    }
  },
  methods: {
    // 提交邀請碼
	async submitGoodCode(intviation_code){
		this.codeBtnDisabled = true
		this.intviation_code = intviation_code
		
		const response =  await this.$api.post('/ebapi/pink_api/secret_intviation_check', {
		  code: intviation_code
		})
		if(response.code === 200){
			this.codeBtnDisabled = false
			this.$refs.codeInputPopup.close()
		}else{
			this.codeBtnDisabled = false
			this.$refs.codeInputPopup.close()
			this.$api.msg(response.msg)
		 }
		},
	codeInputClose(){
	  this.$refs.codeInputPopup.close()
	  this.codeBtnDisabled = false
	}
}
</script>

子組件

<template>
  <view>
    <view class="code-popup-top">
      <view class="code-title">請輸入商品邀請碼</view>
      <view class="close-icon" @click="codeInputClose">
        <uni-icons type="closeempty" size="30" color="#999999" />
      </view>
    </view>
    <!-- 錯誤提示 -->
    <view class="code_errow" v-if="codeColor == '#ff0000'&& !isNum">邀請碼必須{{ codeLength }}位數</view>
    <view class="code_errow" v-if="codeColor == '#ff0000'&& isNum ">邀請碼必須是數字</view>
    <view class="code_input_con">
      <view
        v-for="(item, index) in codeLength"
        :key="index"
        class="code_input_item"
        :
        @click="focus = true"
      >{{ intviation_code[index] && intviation_code[index] || '' }}</view>
      <input
        class="cinput"
        type="tel"
        v-model="intviation_code"
        :maxlength="codeLength"
        :focus="focus"
        :cursor="intviation_code.length"
        @focus="focus = true "
        @blur="focus = false"
      />
    </view>
    <button
      :class="['submit_code_btn', disabled ? 'btn_disabled' : '']"
      :disabled="disabled"
      @click="submitGoodCode"
    >確定</button>
  </view>
</template>

<script>
export default {
  data() {
    return {
      codeColor: '#313131', //自定義錯誤碼顏色
      intviation_code: '', //用戶輸入的驗證碼
      focus: false, // 動態(tài)獲取焦點的值
      isNum: false,
    }
  },
  props: {
    codeLength: {
      type: Number,
      default: 5,
    },
    disabled: {
      type: Boolean,
      default: false,
    },
  },
  methods: {
    codeInputClose() {
      this.intviation_code = ''
      this.$emit('codeInputClose')
    },
    submitGoodCode() {
      if (this.intviation_code.length === this.codeLength) {
        if (Number(this.intviation_code)) {
          this.$emit('submitGoodCode', this.intviation_code)
        } else {
          this.isNum = true
          this.publicErrorSetting()
        }
      } else {
        this.publicErrorSetting()
      }
    },
    // 輸入不符合規(guī)范,更改樣式并清空
    publicErrorSetting() {
      this.codeColor = '#ff0000'
      setTimeout(() => {
        this.intviation_code = ''
        this.codeColor = '#313131'
        this.isNum = false
      }, 1000)
    },
  },
}
</script>

<style lang="scss" scoped>
.code-popup-top {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 50upx;
  .code-title {
    font-size: 34upx;
    color: #333;
    font-weight: bold;
    position: relative;
    &::before {
      content: '';
      position: absolute;
      bottom: 0;
      width: 40upx;
      height: 19upx;
      background: linear-gradient(
        to right,
        rgba(57, 181, 74, 1),
        rgba(57, 181, 74, 0.1)
      );
    }
  }
  .close-icon {
    background: #f2f4f7;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
  }
}
.code_errow {
  font-size: 30upx;
  color: #ff5500;
  margin-bottom: 20upx;
}
.submit_code_btn {
  width: 100%;
  height: 83upx;
  line-height: 83upx;
  border-radius: 7upx;
  background: #39b54a;
  color: #fff;
  font-size: 31upx;
  text-align: center;
  margin-top: 45upx;
}
.btn_disabled {
  color: rgba(255, 255, 255, 0.5) !important;
  background-color: rgba(57, 181, 74, 0.4) !important;
}
.code_input_con {
  display: flex;
  justify-content: space-around;
  position: relative;
  .code_input_item {
    margin-left: 10upx;
    text-align: center;
    line-height: 88upx;
    border-radius: 14upx;
    width: 88upx;
    height: 88upx;
    font-size: 60upx;
    font-weight: bold;
    color: #333;
    &:last-child {
      margin-right: 0;
    }
  }
  /*input隱藏掉*/
  .cinput {
    position: absolute;
    top: 0;
    left: -100%; 
    width: 100%;
    height: 100%;
  }
}
</style>

四. 過程中遇到的問題

1)input 的type=&lsquo;number&rsquo;, ios手機正常,光標在內容最后,但Android手機光標有時候在內容最前面,導致聚焦內容刪不掉。

修改input 的type = 'tel',:cursor="intviation_code.length", 這樣cursor屬性才生效,并指定focus時光標的位置在內容最后;
type=&lsquo;tel&rsquo;,也會有個小問題,可以輸入一些字符,但是我們的需求只能是數字,所以代碼中要做限制。就能解決這個問題了。

這個cursor無效的問題,在h6模式應該是type的原因,我試了在type是number或digit時cursor就無效,text、tel、idcard就有效

2)還有另外一種方法

  • 設置input的type=“number”,就不需要設置光標位置了;然后隱藏input文字和光標,相當于間接隱藏了input框;

  • 用到了css樣式設置,color: transparent; caret-color: transparent;

  • 最主要的還是相對于父元素做絕對定位,與父元素左邊距設置為負的本身寬度的一半即可(position: absolute; top: 0; left:-100%; width: 200%; height: 100%;)with: 200%為了增大點擊區(qū)域,解決Android機型再次喚起鍵盤不能聚焦,刪不掉錯誤數字的問題。

張鑫旭的CSS改變插入光標顏色caret-color簡介及其它變色方法
自我測試CSS : caret-color

<template>
  <view>
      <input
        class="cinput"
        type="number"
        v-model="intviation_code"
        :maxlength="codeLength"
        :focus="focus"
        @focus="focus = true "
        @blur="focus = false"
      />
    </view>
  </view>
</template>

<script>
export default {
  data() {
    return {
      intviation_code: '', //商品邀請碼
      focus: false,
    }
  },
  methods: {}
</script>

<style lang="scss" scoped>
.cinput {
    position: absolute;
    top: 0;
    left: -100%;
    width: 200%;
    height: 100%;
    color: transparent;  //輸入文字顏色透明
    caret-color: transparent !important; //改變插入光標顏色為透明
  }
  }
  // 考慮兼容性
  // 瀏覽器支持caret-color屬性,優(yōu)先使用caret-color(Chrome/Firefox/Opera);其次使用::first-line方法(Safari);最后忽略(如IE)。
  @supports (-webkit-mask: none) and (not (caret-color: transparent)) {
    .cinput {
      color: transparent !important;
    }
    .cinput::first-line {
      color: transparent !important;
    }
  }
</style>

感謝各位的閱讀,以上就是“uniapp怎么自定義驗證碼輸入框并隱藏光標”的內容了,經過本文的學習后,相信大家對uniapp怎么自定義驗證碼輸入框并隱藏光標這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI