vue 表单输入格式化中文输入法异常问题


Posted in Javascript onMay 30, 2018

v-model 是 vue.js 提供的语法糖,根据不同的表单控件监听不同的事件,实现对表单控件的数据双向绑定。

当控件是 <input> 输入框时,v-model 监听其 input 事件。

如下所示,这两种写法有什么区别吗?

<input :value="name" @input="name = $event.target.value"><input v-model="name">

输入中文格式化问题

表单输入常见需求:对<input>控件输入的内容进行格式化,譬如:转成大写字母。如果输入的值包含中文,格式化就会引起输入法异常。

如下图所示,也可以在线尝试:

vue 表单输入格式化中文输入法异常问题

如果使用 v-model 指令实现数据双向绑定,就不会出现输入法异常,如下图所示,也可以在线尝试:

vue 表单输入格式化中文输入法异常问题

上面的问题,可以看出 v-model 不只是给变量赋值,那么,它还做了些什么呢?

v-model 源码分析

本文参考的 vue.js 源代码是 2.5.16

翻看 v-model 源码,可以看到 v-model 关注的仍然是 input 事件:

vue 表单输入格式化中文输入法异常问题

input 事件绑定的回调代码处理,如下:

vue 表单输入格式化中文输入法异常问题

这里可以看到,v-model 判断了 composing 属性,当输入法组合没有结束的时候,直接返回,并没有赋值。

composing 属性并不是标准 dom 元素属性,那它是怎么来的呢?

vue 表单输入格式化中文输入法异常问题

这里可以看出,composing 属性是 vue.js 添加到 dom 节点上的。

那么,是什么地方调用了这2个函数呢?可以看到,在插入dom节点时,vue.js 监听了 compositionstart / compositionend 事件:

vue 表单输入格式化中文输入法异常问题

compositionstart / compositionend 这2个 dom 事件,浏览器兼容性问题可以查阅 MDN 说明:

compositionstart 事件

compostionend 事件

源代码中还发现,在是否刷新 dom 属性值时,也用到了 composing 属性:

vue 表单输入格式化中文输入法异常问题

这里可以看出,在输入法组合过程中,vue.js 变量值的更新亦不会同步到 dom元素的 value 属性。

综上所述:

v-model 实际上是监听了 <input> 控件的 input、compositionstart、compositionend 三个事件,在输入法组合过程中就直接返回不赋值v-model 指令设置了变量 composing,此标识还用于判断是否更新 dom元素的 value 属性

v-model 输入中文触发的事件

从上面源代码分析可知,v-model 绑定 <input> 输入中文时,实际触发的事件如下:

vue 表单输入格式化中文输入法异常问题

vue 表单输入格式化中文输入法异常问题

compositionstart => 3个 input => compositionend 事件,这些都是 <input>控件触发的。最后一个 input 事件,是源代码里面看到的 onCompositionEnd 回调里面 vue.js 触发的。

1、compositionstart事件

修改dom对象的composing属性为 true

2、3个input事件

由于dom对象的composing属性为true,不会赋值,直接返回。

3、compositioinend事件

修改dom对象的composing属性为 false

4、vue.js触发的 input事件

由于dom对象的composing属性为false,赋值,修改相应变量的值。

格式化问题原因分析

再次看下文章开头的示例,如果使用 v-model 指令实现数据双向绑定,就不会出现输入法异常,如下图所示,也可以在线尝试:

vue 表单输入格式化中文输入法异常问题

由前面的分析可知:

v-model 指令设置了变量 composing,虽然代码在 format 函数里更改了 this.name 的值,但此时 composing 标识阻止了将 this.name 的值同步给 input 元素的 value 属性如果你感兴趣的话,可以修改 vue.js 的源代码,将 shouldUpdateValue 函数里对 composing 属性的判断去掉,可以看到输入法又跟之前一样异常了

格式化问题 bugfix

再次看下文章开头的示例,如果使用 :value, @input 实现数据双向绑定,有两个方案可以解决中文输入异常的问题。

方案一:监听 change 事件

等输入结束失去焦点以后,再调用格式化方法,如下所示,也可以在线尝试:

方案二:监听 input 事件,同时判断输入法组合过程

在输入法组合过程中,不进行格式化,如下所示,也可以在线尝试:

总结

以上所述是小编给大家介绍的vue 表单输入格式化中文输入法异常问题,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
再谈javascript 动态添加样式规则 W3C校检
Dec 25 Javascript
javascript 广告后加载,加载完页面再加载广告
Nov 25 Javascript
jquery写个checkbox——类似邮箱全选功能
Mar 19 Javascript
js采用map取到id集合组并且实现点击一行选中一行
Dec 16 Javascript
javascript实现回到顶部特效
May 06 Javascript
JS+CSS实现滑动切换tab菜单效果
Aug 25 Javascript
极简主义法编写JavaScript类
Nov 02 Javascript
Vue cli 引入第三方JS和CSS的常用方法分享
Jan 20 Javascript
JS点击动态添加标签、删除指定标签的代码
Apr 18 Javascript
vue2.0$nextTick监听数据渲染完成之后的回调函数方法
Sep 11 Javascript
ES6 Proxy实现Vue的变化检测问题
Jun 11 Javascript
js神秘的电报密码 哈弗曼编码实现
Sep 10 Javascript
详解如何使用babel进行es6文件的编译
May 29 #Javascript
基于打包工具Webpack进行项目开发实例
May 29 #Javascript
JavaScript反射与依赖注入实例详解
May 29 #Javascript
使用webpack3.0配置webpack-dev-server教程
May 29 #Javascript
vuejs 切换导航条高亮(路由菜单高亮)的方法示例
May 29 #Javascript
微信小程序6位或多位验证码密码输入框功能的实现代码
May 29 #Javascript
Vue 全局loading组件实例详解
May 29 #Javascript
You might like
CI框架扩展系统核心类的方法分析
2016/05/23 PHP
PHP7新特性foreach 修改示例介绍
2016/08/26 PHP
php获取数据库中数据的实现方法
2017/06/01 PHP
PHP数据库操作四:mongodb用法分析
2017/08/16 PHP
浅谈laravel 5.6 安装 windows上使用composer的安装过程
2019/10/18 PHP
Laravel框架处理用户的请求操作详解
2019/12/20 PHP
基于jquery的图片懒加载js
2010/06/30 Javascript
javascript天然的迭代器
2010/10/29 Javascript
jquery select 设置默认选中的示例代码
2014/02/07 Javascript
JQuery下拉框应用示例介绍
2014/04/23 Javascript
浅谈jQuery中replace()方法
2015/05/13 Javascript
jquery实现仿新浪微博评论滚动效果
2015/08/06 Javascript
3种js实现string的substring方法
2015/11/09 Javascript
全国省市二级联动下拉菜单 js版
2016/05/10 Javascript
javascript实现标签切换代码示例
2016/05/22 Javascript
深入解析桶排序算法及Node.js上JavaScript的代码实现
2016/07/06 Javascript
JS触发服务器控件的单击事件(详解)
2016/08/06 Javascript
js从数组中删除指定值(不是指定位置)的元素实现代码
2016/09/13 Javascript
Node.js的Mongodb使用实例
2016/12/30 Javascript
js鼠标跟随运动效果
2017/03/11 Javascript
基于vue打包后字体和图片资源失效问题的解决方法
2018/03/06 Javascript
Node.js中的child_process模块详解
2018/06/08 Javascript
Vue+ElementUI使用vue-pdf实现预览功能
2019/11/26 Javascript
js实现双人五子棋小游戏
2020/05/28 Javascript
windows系统下Python环境的搭建(Aptana Studio)
2017/03/06 Python
python一键去抖音视频水印工具
2018/09/14 Python
在vscode中配置python环境过程解析
2019/09/28 Python
树莓派4B+opencv4+python 打开摄像头的实现方法
2019/10/18 Python
Python基于pygame实现单机版五子棋对战
2019/12/26 Python
前端实现背景虚化但内容清晰且自适应 的实例代码
2019/08/01 HTML / CSS
黄色火烈鸟:De Gele Flamingo
2019/03/18 全球购物
商务英语求职自荐信范文
2013/12/24 职场文书
聘用意向书范本
2014/04/01 职场文书
幼儿园爱国卫生月活动总结
2014/06/30 职场文书
运动会班级口号霸气押韵
2015/12/24 职场文书
Python实现学生管理系统(面向对象版)
2021/06/24 Python