赞
踩
背景:Vue开发移动端应用时,难免用到表单输入,比如金额。
需求:这时就需要吊起移动端数字键盘,input的type就必须设置成number,当然tel类型也可以,但是无法输入小数点。当然如果精力允许,你也可以自定义数字键盘是最好的,网上也有很多Vue数字键盘组件。
踩坑:一但用了input[type=number]类型有很多的坑。
思路一:用原生oninput函数实现输入正则替换,自定义函数替换字符。(会破坏vue统一性,不推荐)
思路二:用vue的@nput函数实现输入正则替换,自定义函数替换字符。(实现麻烦,不推荐)
思路三:用vue的变量监听函数。(输入某些值情况下不会被触发,不推荐)
<input class="amount-input" size="10" maxlength="6" type="number" placeholder="请输入金额" v-model.number="formData.amount">
- watch:{
- 'formData.amount':function (newVal,oldVal) {
- // 解决数字键盘可以输入输入多个小数点问题
- if(newVal==='' && oldVal.toString().indexOf('.')>0){
- this.formData.amount = oldVal;
- return ;
- }
- // 保留两位小数
- if(newVal){
- newVal = newVal.toString();
- var pointIndex = newVal.indexOf('.');
- if(pointIndex>0 && (newVal.length - pointIndex)>3){
- this.formData.amount = oldVal;
- return ;
- }
- }
- // 最大值
- if(newVal>999999){
- this.formData.amount = oldVal;
- return ;
- }
- }
- }
上面的方法解决了,可以多次输入小数点问题,和保留小数位数,还有限制大小都可以在这里实现,因为监听函数可以获取到历史输入值,很方便还原,不过在输入点的时候不会被触发,所以不是很理想。
思路四:用vue的computed函数,实现父组件和子组件双向通信。(为了方便大家使用我单独封装了一个插件MyNumberInput.vue,推荐,推荐,推荐,完美)
path:@/components/Plugin/Form/MyNumberInput.vue
- <template>
- <input class="my-number-input" type="number" :placeholder="placeholder" v-model.number="inputModel">
- </template>
- <script type="text/ecmascript-6">
- export default {
- components: {},
- props: {
- point:{
- default: 0
- },
- max:Number,
- placeholder:String,
- value: {
- default: null
- },
- },
- computed:{
- inputModel: {
- get:function() {
- // 父组件==>子组件 发消息
- return this.value;
- },
- set:function (value) {
-
- // 子组件==>父组件 发消息
- let val = this.$el.value;
- let len = val.length;
- console.log(val);
-
- // 解决首位直接输入 '0开头的数字'问题
- if(len==2 && val.charAt(0)==0 && val.charAt(1)!='.'){
- this.$el.value = val.charAt(1);
- this.setParentModeVal(this.$el.value);
- return;
- }
-
- // 解决数字键盘可以输入输入多个小数点问题
- if(Math.abs(this.value) > 0 && val==='' && value ===''){
- if(this.keyDownDel){
- this.$el.value = '';// 正常删除
- console.log('---正常删除---'+this.value);
- }else {
- this.$el.value = this.value;// 多次输入小数点时
- console.log('---多次输入小数点---'+this.value);
- }
- this.setParentModeVal(this.$el.value);
- return ;
- }
-
- // 解决开始就输入点问题
- if(this.value === '' && val === '' && value === ''){
- console.log('---22aa---'+this.value);
- this.$el.value = '';
- this.setParentModeVal('');
- return ;
- }
-
- // 解决保留两位小数问题
- if(val){
- let pointIndex = val.indexOf('.');
- if(this.point==0 && len==2 && val.charAt(pointIndex)=='.'){
- console.log('只能输入整数');
- this.$el.value = val.substr(0,pointIndex);
- this.setParentModeVal(this.$el.value);
- return ;
- }
- if(pointIndex>0 && (len - pointIndex)>(this.point+1)){
- console.log('只能输入'+this.point+'位小数');
- this.$el.value = val.substr(0,pointIndex + this.point +1);
- this.setParentModeVal(this.$el.value);
- return ;
- }
- }
-
- // 解决输入最大值问题
- if(this.max>0 && val>this.max){
- console.log('---4---')
- this.$el.value = val.substr(0,len-1);
- this.setParentModeVal(this.$el.value);
- return;
- }
-
- this.setParentModeVal(val);
- return;
- }
- }
- },
- data() {
- return {
- keyDownDel:false,// 判断键盘输入值
- }
- },
- mounted() {
- // 判断键盘是否是删除动作
- var that = this;
- window.document.onkeydown = function(event){
- let e = event || window.event || arguments.callee.caller.arguments[0];
- if(e.keyCode==8||e.keyCode==46){
- that.keyDownDel = true;
- }else {
- that.keyDownDel = false;
- }
-
- };
- },
- methods: {
- setParentModeVal(value){
- this.value = value;
- this.$emit('input', value);
- }
- },
- }
- </script>
-
- <style lang="stylus" rel="stylesheet/stylus">
- .my-number-input{
- //user-select: auto;
- //border: 1px solid #ccc; // 去除默认未选中状态边框
- //outline: none; // 去除默认选中状态边框
- //background-color: rgba(0, 0, 0, 0);// 透明背景
- //padding: 2px;
- }
- </style>
组件使用:
1. 导入:
import MyNumberInput from '@/components/Plugin/Form/MyNumberInput';
2. 注册:
- export default {
- components: {
- MyNumberInput //注册
- },
- data() {
- },
- mounted() {
- },
- }
3. 视图:
<MyNumberInput :point="2" :max="99999" placeholder="请输入金额" v-model.number="formData.amount"></MyNumberInput>
属性说明:
解决问题:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。