vue 表單輸入格式化中文輸入法異常問題
v-model 是 vue.js 提供的語法糖,根據(jù)不同的表單控件監(jiān)聽不同的事件,實現(xiàn)對表單控件的數(shù)據(jù)雙向綁定。
當(dāng)控件是 <input> 輸入框時,v-model 監(jiān)聽其 input 事件。
如下所示,這兩種寫法有什么區(qū)別嗎?
<input :value="name" @input="name = $event.target.value"><input v-model="name">
輸入中文格式化問題
表單輸入常見需求:對<input>控件輸入的內(nèi)容進(jìn)行格式化,譬如:轉(zhuǎn)成大寫字母。如果輸入的值包含中文,格式化就會引起輸入法異常。
如下圖所示,也可以在線嘗試:

如果使用 v-model 指令實現(xiàn)數(shù)據(jù)雙向綁定,就不會出現(xiàn)輸入法異常,如下圖所示,也可以在線嘗試:

上面的問題,可以看出 v-model 不只是給變量賦值,那么,它還做了些什么呢?
v-model 源碼分析
本文參考的 vue.js 源代碼是 2.5.16
翻看 v-model 源碼,可以看到 v-model 關(guān)注的仍然是 input 事件:

input 事件綁定的回調(diào)代碼處理,如下:

這里可以看到,v-model 判斷了 composing 屬性,當(dāng)輸入法組合沒有結(jié)束的時候,直接返回,并沒有賦值。
composing 屬性并不是標(biāo)準(zhǔn) dom 元素屬性,那它是怎么來的呢?

這里可以看出,composing 屬性是 vue.js 添加到 dom 節(jié)點上的。
那么,是什么地方調(diào)用了這2個函數(shù)呢?可以看到,在插入dom節(jié)點時,vue.js 監(jiān)聽了 compositionstart / compositionend 事件:

compositionstart / compositionend 這2個 dom 事件,瀏覽器兼容性問題可以查閱 MDN 說明:
源代碼中還發(fā)現(xiàn),在是否刷新 dom 屬性值時,也用到了 composing 屬性:

這里可以看出,在輸入法組合過程中,vue.js 變量值的更新亦不會同步到 dom元素的 value 屬性。
綜上所述:
v-model 實際上是監(jiān)聽了 <input> 控件的 input、compositionstart、compositionend 三個事件,在輸入法組合過程中就直接返回不賦值v-model 指令設(shè)置了變量 composing,此標(biāo)識還用于判斷是否更新 dom元素的 value 屬性
v-model 輸入中文觸發(fā)的事件
從上面源代碼分析可知,v-model 綁定 <input> 輸入中文時,實際觸發(fā)的事件如下:


compositionstart => 3個 input => compositionend 事件,這些都是 <input>控件觸發(fā)的。最后一個 input 事件,是源代碼里面看到的 onCompositionEnd 回調(diào)里面 vue.js 觸發(fā)的。
1、compositionstart事件
修改dom對象的composing屬性為 true
2、3個input事件
由于dom對象的composing屬性為true,不會賦值,直接返回。
3、compositioinend事件
修改dom對象的composing屬性為 false
4、vue.js觸發(fā)的 input事件
由于dom對象的composing屬性為false,賦值,修改相應(yīng)變量的值。
格式化問題原因分析
再次看下文章開頭的示例,如果使用 v-model 指令實現(xiàn)數(shù)據(jù)雙向綁定,就不會出現(xiàn)輸入法異常,如下圖所示,也可以在線嘗試:

由前面的分析可知:
v-model 指令設(shè)置了變量 composing,雖然代碼在 format 函數(shù)里更改了 this.name 的值,但此時 composing 標(biāo)識阻止了將 this.name 的值同步給 input 元素的 value 屬性如果你感興趣的話,可以修改 vue.js 的源代碼,將 shouldUpdateValue 函數(shù)里對 composing 屬性的判斷去掉,可以看到輸入法又跟之前一樣異常了
格式化問題 bugfix
再次看下文章開頭的示例,如果使用 :value, @input 實現(xiàn)數(shù)據(jù)雙向綁定,有兩個方案可以解決中文輸入異常的問題。
方案一:監(jiān)聽 change 事件
等輸入結(jié)束失去焦點以后,再調(diào)用格式化方法,如下所示,也可以在線嘗試:
方案二:監(jiān)聽 input 事件,同時判斷輸入法組合過程
在輸入法組合過程中,不進(jìn)行格式化,如下所示,也可以在線嘗試:
總結(jié)
以上所述是小編給大家介紹的vue 表單輸入格式化中文輸入法異常問題,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復(fù)大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!
相關(guān)文章
vue數(shù)據(jù)傳遞--我有特殊的實現(xiàn)技巧
這篇文章主要介紹了vue數(shù)據(jù)傳遞一些特殊梳理技巧,需要的朋友可以參考下2018-03-03
moment轉(zhuǎn)化時間戳出現(xiàn)Invalid Date的問題及解決
這篇文章主要介紹了moment轉(zhuǎn)化時間戳出現(xiàn)Invalid Date的問題及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-05-05
vue+antDesign實現(xiàn)樹形數(shù)據(jù)展示及勾選聯(lián)動
本文主要介紹了vue+antDesign實現(xiàn)樹形數(shù)據(jù)展示及勾選聯(lián)動,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-02-02
Vue+ElementUi實現(xiàn)點擊表格中鏈接進(jìn)行頁面跳轉(zhuǎn)與路由詳解
在vue中進(jìn)行前端網(wǎng)頁開發(fā)時,通常列表數(shù)據(jù)用el-table展示,下面這篇文章主要給大家介紹了關(guān)于Vue+ElementUi實現(xiàn)點擊表格中鏈接進(jìn)行頁面跳轉(zhuǎn)與路由的相關(guān)資料,文中通過實例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-02-02
建立和維護(hù)大型 Vue.js 項目的 10 個最佳實踐
這篇文章小編要與大家分享的是建立和維護(hù)大型 Vue.js 項目的 10 個最佳實踐,需要的小伙伴請和小編一起學(xué)習(xí)下面文章的具體內(nèi)容吧2021-09-09
nginx+vue.js實現(xiàn)前后端分離的示例代碼
這篇文章主要介紹了nginx+vue.js實現(xiàn)前后端分離的示例代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-02-02

