The project in Vue, based on Vux-ui development, is a common requirement:
1, the amount of input box 2, pop-up number keypad 3, only support input two decimal places, limit the maximum 11 digits, do not allow 0 start
First, the first thought is the vux-ui in the development of Type=number. --Not OK
Vux in the document and code description, Type=number does not support MaxLength, will be error, and there is no regular replacement of the processing or hook function, only after input prompt check information.
Second, based on the XInput package in Vux, there are the following problems
1) Two-layer V-model, the value of the regular replacement does not trigger the input box rendering
FIX: CurrentValue assignment is foramttedvalue, put into settimeout (func, 0), let input box first render as the value before the regular replacement, and then render as the replaced value
CurrentValue (val, oldval) {//filter data by calling filterLet FormattedValue = This. Filter (val); if( This. Type = = = ' Number ') {FormattedValue= This. Typenumberfilter (FormattedValue, oldval); } if(val!== formattedvalue | | val = = = ") {setTimeout ()= { This. CurrentValue =FormattedValue; }, 0); } This. $emit (' input ', FormattedValue); },
View Code
2) numeric keypad input type=number, can cause maxlength to fail, cannot limit the length
Workaround: Use Slice (0, max) to process
if This . Max) { this. max); }
View Code
3) numeric keypad input type=number, continuous input decimal point ... Cause actual and display values to be inconsistent
Resolution: treated with native Inputelement.value = OldValue
Const Inputele = This. $children [0]. $refs. Input; //TODO: Pending wide-range validation: process continuous input. , the Type=number input box will change the value to "' problem; Fastclick causes type=number error //Problem Description: 1.00. No trigger value change, 1.00. Value change not triggered, 1.00. "\d\." will change the value to an empty string '. The conditions for hack processing are described below: //1, when the check is null, (because Input=number,formattedvalue "indicates that the original newval also") //2, the input box to get a null value (because Input=number causes the input box is immediately assigned to null value. Click the Clear button, here input box or last value) //3, last input greater than two bits (to avoid the last one can not delete the problem. When the last one is deleted, oldval.length = = = 1) if(FormattedValue = = = ' && Inputele.value = = = ' && oldval && oldval.match (/^ (\d) [\d.] +/) ) {FormattedValue=Oldval; } setTimeout (()={Inputele.value=FormattedValue; }, 0);
View Code
4) The numeric keypad in iOS has special characters such as%$*
Resolution: Monitor events with native Inputelement.onkeydown, non-numeric and backspace and decimal point direct return events
mounted () {if( This. Type = = = ' Number ') {Const Inputele= This. $refs. xinput. $refs. Input; //Eslint-disable-next-lineInputele.onkeydown = (e) = ={Const KeyCode=E.keycode; if(! This. Isbackspace (keycode) &&! This. Isdot (keycode) &&! This. Isnumber (KeyCode)) { //Other keysE.preventdefault (); E.stoppropagation (); return false; } }; } }
View Code
Third, other notes
Why not Type=tel?
Type=tel no decimal point in iOS
Four, all the code
<template> <Xinput:title= "title": Max= "Currentmax": Min= "Currentmin": Type= "Type"v-model= "CurrentValue"@on-focus= "Onfoucus ()"@on-blur= "OnBlur ()": Show-clear= "Showclear":p Laceholder= "Placeholder"ref= "XInput" > <template v-if= "$slots. Label" slot= "label" ><slot name= "label" ></slot></template> <template V-if= "$slots. Right" slot= "right" ><slot name= "right" ></slot></template> </xinput></ Template><script>Exportdefault{data () {return{currentvalue: This. Value,}; }, computed: {Currentmax () {return( This. Type = = = ' number ')? Undefined: This. Max; }, Currentmin () {return( This. Type = = = ' number ')? Undefined: This. Min; }}, props: {title:string, Max:number, Min:number, type:string, showclear: {Type:boolean, default:true,}, Placeholder:string, value: [String, Number], filter: {type:function,default: (value) = ={Let formattedvalue= ' '; Const Match= Value.match (/^ ([1-9]\d* (\.[ \d]{0,2})? | 0 (\.[ \d]{0,2})?) [\d.] */); if(Match) {FormattedValue= Match[1]; } returnFormattedValue; },}, watch: {CurrentValue (val, oldval) {//filter data by calling filterLet FormattedValue = This. Filter (val); if( This. Type = = = ' Number ') {FormattedValue= This. Typenumberfilter (FormattedValue, oldval); } if(val!== formattedvalue | | val = = = ") {setTimeout ()= { This. CurrentValue =FormattedValue; }, 0); } This. $emit (' input ', FormattedValue); }, value (value) { This. CurrentValue =value; },}, methods: {Onfoucus () { This. $emit (' On-focus '); }, OnBlur () { This. $emit (' On-blur '); }, Typenumberfilter (Val, oldval) {const Inputele= This. $refs. xinput. $refs. Input; Let FormattedValue=Val; //since Type=number does not support maxlength, it is simulated with slice if(Formattedvalue.length > This. Max) {FormattedValue= Formattedvalue.slice (0, This. Max); } //TODO: Pending wide-range validation: process continuous input. , the Type=number input box will change the value to "' problem; Fastclick causes type=number error //Problem Description: 1.00. No trigger value change, 1.00. Value change not triggered, 1.00. "\d\." will change the value to an empty string '. The conditions for hack processing are described below: //1, when the check is null, (because Input=number,formattedvalue "indicates that the original newval also") //2, the input box to get a null value (because Input=number causes the input box is immediately assigned to null value. Click the Clear button, here input box or last value) //3, last input greater than two bits (to avoid the last one can not delete the problem. When the last one is deleted, oldval.length = = = 1) if(FormattedValue = = = ' && Inputele.value = = = ' && oldval && oldval.match (/^ (\d) [\d.] +/) ) {FormattedValue=Oldval; } setTimeout (()={Inputele.value=FormattedValue; }, 0); returnFormattedValue; }, Isbackspace (keycode) {returnKeyCode = = 8; }, Isdot (keycode) {returnKeyCode = = 46 | | KeyCode = = 110 | | KeyCode = = 190; }, Isnumber (keycode) {return(KeyCode >= && keycode <= 57) | | (KeyCode >= && keycode <= 105); },}, mounted () {if( This. Type = = = ' Number ') {Const Inputele= This. $refs. xinput. $refs. Input; //Eslint-disable-next-lineInputele.onkeydown = (e) = ={Const KeyCode=E.keycode; if(! This. Isbackspace (keycode) &&! This. Isdot (keycode) &&! This. Isnumber (KeyCode)) { //Other keysE.preventdefault (); E.stoppropagation (); return false; } }; } }};</script>
View Code
Notes Mobile H5 The processing of the numeric keypad input type=number (iOS and Android)