亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

vue自定義密碼輸入框解決瀏覽器自動填充密碼的問題(最新方法)

 更新時間:2023年04月17日 09:14:13   作者:longxiaoming  
這篇文章主要介紹了vue自定義密碼輸入框解決瀏覽器自動填充密碼的問題,通過將密碼輸入框的type設(shè)置為text,修改樣式上的顯示,來實現(xiàn)既可以讓瀏覽器不自動填充密碼,又可以隱藏密碼的效果,需要的朋友可以參考下

問題描述

瀏覽器對于type="password"的輸入框會自動填充密碼,但有時出于安全或者其他原因,我們不希望瀏覽器記住并自動填充密碼。通過網(wǎng)上查到的一些解決方案,可以總結(jié)出以下幾種解決方案(主要用edge瀏覽器進行測試):

  • 通過autocomplete="off"/autocomplete="new-password"來關(guān)閉瀏覽器自動填充密碼的功能, 但某些對于瀏覽器像edge,firfox等,這種方法并不起作用
  • 通過type="text"來解決,當focus時,通過js將type="text"改為type="password"。
<input type="text" onfocus="this.type='password'">

但同樣對某些瀏覽器不起作用,如edge,在點擊輸入框時,仍會自動彈出填充密碼的提示框。

3.某些瀏覽器可能只會識別第一個type="password"的輸入框,所以可以在前面添加一些隱藏的type="password"的輸入框,來解決這個問題。

<form style="display:none">
  <input type="password">
</form>
<input type="password" style="display:none">
<input type="password">

但同樣并不是總是有效,拿edge測試時即使前幾個密碼輸入框沒有隱藏,最后一個輸入框也會自動填充密碼,如圖:

4.通過readonly屬性來解決,初始化時將readonly設(shè)置為true,通過setTimeout來延時設(shè)置readonlyfalse

<input id="passwordInput" type="password" readonly>
setTimeout(() => {
    document.getElementById('passwordInput').removeAttribute('readonly')
}, 100)

但同樣并非總是有效,拿edge測試時,雖然點擊輸入框時并沒有彈出填充密碼的提示框,但是在輸入框中輸入密碼然后退格到輸入框為空時,又會重新彈出填充密碼的提示框。

上述幾種方法除了會彈出填充密碼的提示框外,在頁面跳轉(zhuǎn)或刷新時(如edge瀏覽器),都會彈出保存密碼的提示框,如圖:

當然,應該還會有其他解決方案我暫時還沒找到,如果有的話,歡迎留言。

自定義密碼輸入框組件解決方案

在嘗試了上述幾種解決方案后,發(fā)現(xiàn)效果都不是很好,所以我感覺只有讓inputtype屬性始終為password,才能更有效的解決這個問題??梢钥紤]自定義一個密碼輸入框組件,通過某些方法去改變input的值的顯示方式,來達到隱藏密碼的效果。
目前想出了兩種方法:一個是不改變input的值,僅僅隱藏input的內(nèi)容,用另一個容器去顯示密碼或者顯示*;另一個是將實際密碼存在另一個變量中,將inputvalue值改成*來顯示。

方案一

可以用兩個input來實現(xiàn),父容器是relative定位,兩個input都是absolute,一個實際的輸入框位于上層,設(shè)置為透明,另一個用于顯示星號的輸入框位于下層。

<div class="container">
  <input v-model="passwordDisplay">
  <input
    v-model="password"
    class="password"
    @input="passwordDisplay = password.replace(/./g, '*')">
</div>

<style scoped>
.container {
  position: relative;
}
.container input {
  position: absolute;
  left: 0;
  top: 0;
  font-size: 12px;
}
.password {
  opacity: 0;
}
</style>

效果如下圖所示:

確實沒有彈出密碼填充的對話框,但樣式上并不是很滿意。因為實際的輸入框被設(shè)置成了透明,且在密碼顯示框之上,所以光標無法顯示出來,且無法進行選中一部分內(nèi)容。

方案二

跟方案一差不多的方式,用input來接收用戶輸入的密碼,但僅改變輸入內(nèi)容的透明度, 由于在opacity為0的情況下設(shè)置光標顏色無效,所以要將方案一中的opacity: 0改為:

.password {
  color: transparent;
  background-color: transparent;
  caret-color: #000; /* 光標顏色 */
}

但是這會有個問題,選中一部分內(nèi)容時,會導致透明的內(nèi)容選中后顯現(xiàn)出來,如圖所示:

這種情況下可以考慮監(jiān)聽選中事件,當選中一部分內(nèi)容時,將后面的星號也選中,同時通過::selection偽類來設(shè)置選中的內(nèi)容的背景色,讓兩個選中的內(nèi)容顏色一致。要實現(xiàn)這種效果,input顯然做不到修改部分內(nèi)容的背景色,所以可以考慮用span代替input,向其innerHTML中插入帶背景色的span

<div class="container">
  <span
    ref="passwordInputDisplay"
    class="password password-input__behind"
  />
  <input
    v-model="password"
    class="password password-input__front"
    @focus="isActive = true"
    @blur="isActive = false"
    @input="passwordDisplay = password.replace(/./g, '*')">
</div>
<style scoped>
::selection {
  background-color: #409eff;
}
.container {
  position: relative;
}
.password {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  font-size: 12px;
  font-family: monospace; /* 必須用等寬字體 */
}
.password-input__behind {
  text-align: left;
  z-index: 1;
}
.password-input__front {
  color: transparent;
  background-color: transparent;
  caret-color: #000;
  z-index: 2;
}

export default {
  props: {
    value: {
      type: String,
      default: ''
    }
  },
  methods: {
    handleInput (e) {
      // 刪除非法字符(只保留code>=32且code<=126的字符)
      const value = e.target.value
      const newValue = value.replace(/[^\x20-\x7E]/g, '')
      if (newValue !== value) {
        this.password = newValue
      }
      // 發(fā)布input事件,從而修改props中的value值
      this.$emit('input', this.password)
    }

  },
  created() {
    this.selectionEvent = () => {
      const display = this.$refs.passwordInputDisplay
      display.style.zIndex = 1
      display.innerHTML = this.passwordDisplay
      if (!this.isActive) { return }
      const selection = window.getSelection()
      // 如果選中的內(nèi)容不為空, 則由passwordInputDisplay顯示
      if (!selection.toString()) { return }
      const input = this.$refs.passwordInput
      const start = input.selectionStart
      const end = input.selectionEnd
      const highlightString = '<span style="background-color: #409eff; color: #fff;">' + this.passwordDisplay.slice(start, end) + '</span>'
      display.innerHTML = this.passwordDisplay.slice(0, start) + highlightString + this.passwordDisplay.slice(end)
      display.style.zIndex = 4
    }
    document.addEventListener('selectionchange', this.selectionEvent)
  },
  beforeDestory() {
    document.removeEventListener('selectionchange', this.selectionEvent)
  }
}

需要注意以下幾點:

  • 監(jiān)聽select事件不能用input自帶的onselect@select,因為這只會在鼠標松開時觸發(fā),并不能實時相應選取區(qū)域的變化。所以要監(jiān)聽selectionchange事件。注意selectionchange事件在沒選中內(nèi)容時也會觸發(fā)。
  • 由于相比方案一顯示了光標,光標的位置會受到實際字符寬度的影響,所以要使星號與其他字符寬度相等,必須使用如monospace之類的等寬字體,且必須阻止中文字符的輸入。
  • 修改innerHtml后需要改變密碼顯示框的z-index,否則仍然會被input中選中的內(nèi)容覆蓋。

效果如下圖所示:

這里還有個問題,當輸入內(nèi)容超過了input的長度,顯示上就會出現(xiàn)錯誤,可以考慮根據(jù)字體寬度計算出最大容納的字符個數(shù),阻止過多字符的輸入。也可以在光標移動時同時移動后面的span,不過邏輯太過復雜沒必要。

const width = this.$refs.passwordInput.clientWidth - 20 // 20為padding
const canvas = document.createElement('canvas')
const ctx = canvas.getContext('2d')
ctx.font = '16px monospace'
const fontWidth = ctx.measureText('A').width
this.maxLength = Math.floor(width / fontWidth)

這里用的是canvas進行計算字體寬度。

雖然最終實現(xiàn)了目標效果,不過邏輯上還是稍微復雜了點。

完整代碼在: https://github.com/lxmghct/my-vue-components
src/components/PasswordInput/PasswordInput1.vue

方案三

只使用一個input,另外設(shè)置一個變量去保存真實密碼。這種方法比上述方法邏輯上要稍微簡單一些,唯一需要注意的就是當輸入框中顯示為星號時,如何區(qū)分哪些是新輸入的內(nèi)容,因為會有鼠標選中一段內(nèi)容再刪除或輸入、粘貼的操作,而新輸入的內(nèi)容中也可能包含星號,所以不能處理的過于簡單。最后采用的是監(jiān)聽selectionchange事件來隨時更新光標所在位置,從而區(qū)分新輸入的內(nèi)容。

const width = this.$refs.passwordInput.clientWidth - 20 // 20為padding
const canvas = document.createElement('canvas')
const ctx = canvas.getContext('2d')
ctx.font = '16px monospace'
const fontWidth = ctx.measureText('A').width
this.maxLength = Math.floor(width / fontWidth)
export default {
  methods: {
    handleInput () {
      // 獲取新輸入的字符
      const tempEnd = this.passwordDisplaylength - (this.password.length - thisselection.end)
      const newStr = this.passwordDisplay.slic(this.selection.start, tempEnd)
      // 更新輸入框的值
      const currentPosition = this.$refspasswordInput.selectionStart
      this.password = this.password.slice(0,Math.min(this.selection.start,currentPosition)) + newStr + this.passwordslice(this.selection.end)
      this.selection.start = currentPosition
      this.selection.end = currentPosition
      this.$emit('input', this.password)
    }
  },
  created () {
    this.selectionEvent = () => {
      if (!this.isActive) { return }
      const input = this.$refs.passwordInput
      this.selection = {
        start: input.selectionStart,
        end: input.selectionEnd
      }
    }
    this.copyEvent = (e) => {
      if (!this.isActive) { return }
      const clipboardData = e.clipboardData || window.clipboardData
      clipboardData.setData('text', this.password.slice(this.selection.start, this.selection.end))
      e.preventDefault()
    }
    document.addEventListener('selectionchange', this.selectionEvent)
    document.addEventListener('copy', this.copyEvent)
  },
  beforeDestroy () {
    document.removeEventListener('selectionchange', this.selectionEvent)
    document.removeEventListener('copy', this.copyEvent)
  }
}

有幾點需要注意:

  • 輸入框中選定的內(nèi)容的起始和結(jié)束位置無法通過window.getSelection().anchorOffset等參數(shù)獲取(window.getSelection()的幾個offset都是0), 只能通過inputselectionStartselectionEnd可以拿到當前選中區(qū)域的起始和結(jié)束位置。
  • 由于輸入框內(nèi)實際顯示的是星號,所以復制時若不處理則復制的也是星號,所以需要監(jiān)聽復制事件,將實際密碼寫入剪貼板。剪貼板通過e.clipboardData || window.clipboardData獲取。

相比于方案二,這種方法無需要求一定要等寬字體,也無需另外去處理選中內(nèi)容的事件,唯一多出的地方就是對輸入框?qū)嶋H值的處理,包括輸入和復制,而這里的邏輯顯然比方案二中修改樣式容易的多。

效果上跟方案二基本差不多,而且沒有長度限制,這里用this.passwordDisplay = '\u2022'.repeat(this.value.length)把星號改成了圓點,如下:

完整代碼在: https://github.com/lxmghct/my-vue-components
src/components/PasswordInput/PasswordInput2.vue

密碼顯示與隱藏

點擊眼睛圖標,切換密碼的顯示與隱藏狀態(tài)。

export default {
  watch: {
    value () {
      this.updatePasswordDisplay()
    },
    showPassword () {
      this.updatePasswordDisplay()
    }
  },
  methods: {
    updatePasswordDisplay () {
      if (this.showPassword) {
        this.passwordDisplay = this.value
      } else {
        // this.passwordDisplay = '*'.repeat(this.value.length)
        this.passwordDisplay = '\u2022'.repeat(this.value.length) // 圓點
      }
    }
  }
}

眼睛圖標可以用圖標庫或者導入圖片,我這里用的是svg,眼睛圖標的svg可以通過一些轉(zhuǎn)換工具來實現(xiàn),這里推薦一個網(wǎng)站: https://picsvg.com/

<div class="password-input__eye-wrap">
  <div
      class="password-input__eye"
      @click="showPassword = !showPassword"
  >
      <svg version="1.0" xmlns="http://www.w3.org/2000/svg"
      width="58.000000pt" height="50.000000pt" viewBox="0 0 58.000000 50.000000"
      preserveAspectRatio="xMidYMid meet">
          <g transform="translate(0.000000,50.000000) scale(0.100000,-0.100000)"
          fill="#000000" stroke="none">
              <path d="M228 390 c-61 -19 -148 -96 -148 -130 0 -21 61 -87 103 -110 50 -29
              127 -32 173 -8 39 21 114 98 114 118 0 19 -74 97 -111 115 -36 19 -98 26 -131
              15z m121 -40 c37 -18 91 -72 91 -90 0 -18 -54 -72 -91 -90 -70 -36 -138 -22
              -206 43 -18 17 -33 38 -33 47 0 19 53 71 95 93 41 22 98 21 144 -3z"/>
              <path d="M235 338 c-31 -18 -44 -40 -45 -75 0 -45 9 -62 42 -79 84 -43 168 60
              106 130 -27 30 -74 41 -103 24z m79 -34 c20 -20 20 -68 0 -88 -35 -35 -104 -6
              -104 44 0 50 69 79 104 44z"/>
          </g>
      </svg>
  </div>
</div>
<style scoped>
.password-input__eye-wrap {
    display: flex;
    align-items: center;
    justify-content: center;
}
.password-input__eye {
    width: 20px;
    height: 20px;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
}
</style>

效果如下:

完整代碼在: https://github.com/lxmghct/my-vue-components
src/components/PasswordInput/PasswordInput2.vue
覺得有幫助的可以在github上點個star~

總結(jié)

通過將密碼輸入框的type設(shè)置為text,修改樣式上的顯示,來實現(xiàn)既可以讓瀏覽器不自動填充密碼,又可以隱藏密碼的效果。

到此這篇關(guān)于vue自定義密碼輸入框解決瀏覽器自動填充密碼的問題的文章就介紹到這了,更多相關(guān)vue自定義密碼輸入框內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • vue-content-loader內(nèi)容加載器的使用方法

    vue-content-loader內(nèi)容加載器的使用方法

    這篇文章主要介紹了vue-content-loader內(nèi)容加載器的使用方法,本文分步驟給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下
    2018-08-08
  • Vue.js系列之項目結(jié)構(gòu)說明(2)

    Vue.js系列之項目結(jié)構(gòu)說明(2)

    這篇文章主要介紹了Vue.js系列之項目結(jié)構(gòu)說明(2)的相關(guān)資料,非常不錯,具有參考借鑒價值,需要的朋友可以參考下
    2017-01-01
  • Vuejs中的watch實例詳解(監(jiān)聽者)

    Vuejs中的watch實例詳解(監(jiān)聽者)

    本文通過實例代碼給大家介紹了Vuejs中的watch,非常不錯,具有一定的參考借鑒價值,需要的朋友參考下吧
    2020-01-01
  • vue實現(xiàn)元素拖動并互換位置的實現(xiàn)代碼

    vue實現(xiàn)元素拖動并互換位置的實現(xiàn)代碼

    在使用Vue的場景下,需要實現(xiàn)對元素進行拖動交換位置,接下來通過本文給大家介紹vue實現(xiàn)元素拖動并互換位置的實現(xiàn)代碼,需要的朋友可以參考下
    2023-09-09
  • VUE項目中引入vue-router的詳細過程

    VUE項目中引入vue-router的詳細過程

    vue-router 也叫 vue 路由,根據(jù)不同的路徑,來執(zhí)行不同的組件,這篇文章主要介紹了VUE項目中引入vue-router,需要的朋友可以參考下
    2023-05-05
  • 一文詳解Vue中nextTick的原理與作用

    一文詳解Vue中nextTick的原理與作用

    Vue的nextTick方法是用于在DOM更新后執(zhí)行回調(diào)的工具函數(shù),它的作用是在當前JavaScript執(zhí)行環(huán)境中延遲執(zhí)行回調(diào),以確保在下次DOM更新循環(huán)之前,可以訪問到更新后的DOM,本文就給大家介紹一下Vue nextTick原理與作用,需要的朋友可以參考下
    2023-08-08
  • 基于vue3+antDesign2+echarts?實現(xiàn)雷達圖效果

    基于vue3+antDesign2+echarts?實現(xiàn)雷達圖效果

    這篇文章主要介紹了基于vue3+antDesign2+echarts?實現(xiàn)雷達圖,本文通過實例代碼圖文相結(jié)合給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-08-08
  • Vue父子之間值傳遞的實例教程

    Vue父子之間值傳遞的實例教程

    這篇文章主要給大家介紹了關(guān)于Vue父子之間值傳遞的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者使用Vue具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧
    2020-07-07
  • vue無限輪播插件代碼實例

    vue無限輪播插件代碼實例

    這篇文章主要介紹了vue無限輪播插件,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-05-05
  • Vue傳遞參數(shù)不在URL路徑拼接顯示問題

    Vue傳遞參數(shù)不在URL路徑拼接顯示問題

    這篇文章主要介紹了Vue傳遞參數(shù)不在URL路徑拼接顯示問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-03-03

最新評論