UI组件库Form表单_数字类型验证之坑实现数字框
目录
Input 输入框
实现数字框封装使用
项目需求 : 使用的饿了么组件库的 input 框 , 但是想要 实现用户只能输入 数字 的功能 ,
So 看到了数字类型的验证 (缺点 :不能阻止用户输入非数字内容 , 只能是给提示警告而已)
但今天在项目里对照着组件库示例代码写都能频繁报错 ,简直大无语啊 。 。 。
所以自己整理一下 , 免得自己以后掉坑 。 。 。
<template><div class="formBox"><div class="infos"><div class="infoBox"><el-form:model="numberValidateForm"ref="numberValidateForm"label-width="100px"class="demo-ruleForm"label-position="left"><el-form-item label="姓名" prop="name" :rules="name"><el-inputv-model="numberValidateForm.name"autocomplete="off"placeholder="请输入姓名"></el-input></el-form-item><el-form-item label="联系电话" prop="phone" :rules="phone"><el-inputv-model="numberValidateForm.phone"autocomplete="off"placeholder="请输入电话号码"></el-input></el-form-item><el-form-item label="树龄" prop="number" :rules="number"><el-inputtype="number"v-model.number="numberValidateForm.number"autocomplete="off"placeholder="请输入树龄"></el-input></el-form-item><el-form-item><el-button type="primary" @click="submitForm('numberValidateForm')">提交</el-button><el-button @click="resetForm('numberValidateForm')">重置</el-button></el-form-item></el-form></div></div></div>
</template>
<script>
const cryptoJs = new CryptoJs();
export default {data() {let checkValue = (rule, value, callback) => {if (!value) {return callback(new Error("值不能为空"));}setTimeout(() => {if (!Number.isInteger(value)) {callback(new Error("请输入数字值"));} else {if (value < 1) {callback(new Error("值必须大于1"));} else {callback();}}}, 200);};return {numberValidateForm: {name: "", // 姓名phone: "", // 电话number: null, // 数量},name: { required: true, message: "姓名不能为空" },phone: { required: true, message: "联系电话不能为空" },number: [{ required: true, validator: checkValue, trigger: ["change", "blur"] },],};},methods: {submitForm(formName) {this.$refs[formName].validate((valid) => {if (valid) {let params = this.numberValidateForm;console.log("验证成功,参数为", params);} else {console.log("数据验证不成功");return false;}});},//重置resetForm(formName) {this.$refs[formName].resetFields();},},
};
</script>
<style lang="scss" scoped>
@import "./index.scss";
</style>
百度的各种写法 :(希望有一个能用得上吧)
<template><div class="formBox"><div class="infos"> <div class="infoBox"><el-form:model="numberValidateForm"ref="numberValidateForm"label-width="100px"class="demo-ruleForm"label-position="left"> <el-form-item label="姓名" prop="name" :rules="name"><el-inputv-model="numberValidateForm.name"autocomplete="off"placeholder="请输入姓名"></el-input></el-form-item><el-form-item label="联系电话" prop="phone" :rules="phone"><el-inputv-model="numberValidateForm.phone"autocomplete="off"placeholder="请输入电话号码"></el-input></el-form-item> <el-form-item label="树龄" prop="number" :rules="number"><el-inputtype="number"v-model.number="numberValidateForm.number"autocomplete="off"placeholder="请输入树龄"></el-input></el-form-item><el-form-item><el-button type="primary" @click="submitForm('numberValidateForm')">提交</el-button><el-button @click="resetForm('numberValidateForm')">重置</el-button></el-form-item></el-form></div></div></div>
</template>
<script>
const cryptoJs = new CryptoJs()
export default {data () {let checkValue = (rule, value, callback) => {if (!value) {return callback(new Error('值不能为空'))}setTimeout(() => {if (!Number.isInteger(value)) {callback(new Error('请输入数字值'))} else {if (value < 1) {callback(new Error('值必须大于1'))} else {callback()}}}, 200)}return {numberValidateForm: {name: '', // 姓名phone: '', // 电话number: null // 数量},name: { required: true, message: '姓名不能为空' },phone: { required: true, message: '联系电话不能为空' },number: [{ required: true, validator: checkValue, trigger: ['change', 'blur'] }]}},methods: {submitForm (formName) {this.$refs[formName].validate((valid) => {if (valid) {let params = this.numberValidateFormconsole.log('验证成功,参数为',params)} else {console.log('数据验证不成功')return false}})},//重置resetForm (formName) {this.$refs[formName].resetFields()}}
}
</script>
<style lang="scss" scoped>
@import "./index.scss";
</style>
form 表单 rules 验证
1. el-form ,设置 :rules="rules" ref="ruleForm"
2. el-form-item ,设置 :prop="name"
3. 具体需验证的字段中 , v-model="name"
4. script 的 data 中 ,
rules:{name:[{required:true,message:'不能为空,请选择菜单名称',trigger:'change'},],}
5. 提交按钮中 ,@click="submit('ruleForm')
6. methods 中 ,
submit(formName) {this.$refs[formName].validate((valid) => {if (valid) {console.log('submit')}else{console.log('error submit');return false;}})
7. 重置校验,在取消按钮或取消事件中,
this.$refs['ruleForm'].resetFields()
以下是完整例子 : 需要注意以下几点:
:model 一定要绑定一个 对象 , 本例子是 editForm , 同时要验证字段的 v-model 绑定数据一定要在 editForm 中 .
同时 prop 绑定的名字要和 v-model 绑定的名字一样 , 这个是很重要, 一般做法是 prop 和 rules 规则还有 v-model 绑定的数据 所有的名称都一样
直观方便, 且不容易出错.<template><div><el-form:model="editForm"ref="editForm":rules="rules"label-position="left"label-width="100px"><el-row :gutter="24"><el-col :span="12"><el-form-item label="姓名"><el-inputv-model="multipleSelectionStudent"placeholder="请选择"></el-input></el-form-item></el-col><el-col :span="12"><el-form-item label="地区" prop="selectSources"><el-cascaderv-model="editForm.selectSources"placeholder="请选择":clearable="true":options="options.resourceGroup"change-on-select:props="cascaderProp"class="el-cascader-100p"></el-cascader></el-form-item></el-col></el-row><button @click="submit">提交</button></el-form></div> </template><script> export default {data() {return {editForm: {selectSources: [],},rules: {selectSources: [{ required: true, message: "请选择", trigger: "change" },],},};},methods: {submitForm(formName) {this.$refs[formName].validate((valid) => {if (valid) {alert("submit!");} else {console.log("error submit!!");return false;}});},}, }; </script><style lang="scss" scoped> </style>
使用过程中遇到的各种报错信息 :
Property or method "numberValidateForm" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components , by initializing the property.
属性或方法“numberValidateForm”未在实例上定义,但在渲染期间被引用。通过初始化属性,确保此属性在数据选项中或对于基于类的组件是被动的。
[Vue warn]: Invalid prop: type check failed for prop "model". Expected Object, got String with value "".
[Vue warn]:无效道具:道具“模型”的类型检查失败。应为对象,获取了值为“”的字符串。
最后自己在项目中所用代码 :
<template><!-- 自定义校验规则 --><div class="formBox"><!-- :model 绑定的一定要是一个 对象 numberValidateForm: {}
否则会报错 : 类型检查失败。应为对象,获取了值为 “” 的字符串 --><el-formlabel-position="top":model="numberValidateForm"ref="numberValidateForm"label-width="200px"class="demo-ruleForm"><el-form-item size="mini"><!-- 文本类型输入框 --><el-inputv-if="item.quInputType === '1'"v-model="item.modelValue"type="textarea":style="`width:${item.answerInputWidth}px`":rows="item.answerInputRow"placeholder="请输入内容"></el-input><!-- 日期类型输入框 --><el-date-pickerv-if="item.quInputType === '2'":readonly="true"v-model="item.dateValue"type="date"placeholder="请选择日期"></el-date-picker><!-- 数字类型输入框 --><!-- prop 要跟 rules 规则里的名字对应一致 --><el-form-itemv-if="item.quInputType === '3'"prop="numValue":rules="numValue"><el-inputsize="small"autocomplete="off"type="numValue"v-model.number="item.numberValidateForm.numValue":maxlength="item.numDigit"@input="handleNumInput('numberValidateForm')"placeholder="请输入数字"></el-input></el-form-item></el-form-item></el-form></div>
</template>
<script>
export default {data() {return {// 在 item 中的数据字段numberValidateForm: {numValue: "", // 数字输入框的绑定值},quInputType: "1", // input 类型 : 1.文本 2.日期 3.数字modelValue: "", // 默认文本域绑定值answerInputWidth: "300", // input 宽度answerInputRow: "1", // input 高度dateValue: "", // 日期选择器绑定值numValue: [{ required: true, message: "内容不能为空" },{ type: "number", message: "内容必须为数字" },],numValue: "", // 数字输入框绑定值numDigit: "1", // 控制数字位数};},methods: {handleNumInput(formName) {// 输入时实时校验/* 注意 : 这里有个大坑啊, 我的 this.$refs[formName]. 一直提示报错 : 不是一个函数通过打印才发现层级出现了点问题, 改成 this.$refs[formName][0] 就 OK 了也不知道是不是只有我的是如此 (如果你也出现了类似情况, 不妨就加上 [0] 试一试吧) */this.$refs[formName][0].validate((valid) => {if (valid) {let params = this.numberValidateForm;console.log("验证成功,参数为", params);} else {console.log("数据验证不成功");return false;}});},},
};
</script>
<style lang="scss" scoped>
</style>
后来呢 , 因为这种方法只能给到一个提示作用 ,却并不能阻止到用户继续输入非数字内容 ,
所以继续百度搜寻方法 ,=> Vue 只能输入数字
不过呢这个有个问题就是使用的 v-bid: value , 来控制的输入框输入内容 ,
所以无法再使用 v-model 来进行双向绑定了 (缺点)
<template><div class="formBox"><el-form label-position="top" label-width="200px" class="demo-ruleForm"><el-form-item size="mini"><!-- 文本类型输入框 --><el-inputv-if="item.quInputType === '1'"v-model="item.modelValue"type="textarea":style="`width:${item.answerInputWidth}px`":rows="item.answerInputRow"placeholder="请输入内容"></el-input><!-- 日期类型输入框 --><el-date-pickerv-if="item.quInputType === '2'":readonly="true"v-model="item.dateValue"type="date"placeholder="请选择日期"></el-date-picker><!-- 数字类型输入框 --><!-- :value 导致 v-model 双向绑定失效 --><!-- v-model.number="item.numValue" --><el-inputv-if="item.quInputType === '3'"size="small":maxlength="item.numDigit"@input="handleNumInput":value="inputNum"placeholder="请输入数字"></el-input></el-form-item></el-form></div>
</template>
<script>
export default {data() {return {// 在 item 中的数据字段numValue: "", // 数字输入框的绑定值quInputType: "1", // input 类型 : 1.文本 2.日期 3.数字modelValue: "", // 默认文本域绑定值answerInputWidth: "300", // input 宽度answerInputRow: "1", // input 高度dateValue: "", // 日期选择器绑定值numValue: "", // 数字输入框绑定值numDigit: "1", // 控制数字位数oldInputNum: "" /* 数字类型输入框初始值 */,};},computed: {inputNum() {return this.oldInputNum;},},methods: {handleNumInput(event) {/* 此方法因为使用了 v-bind:value , 所以原本的 v-model 双向绑定就不能使用了 , 否则此方法会不生效 , 因此就需要我们自己去获取到用户最后输入的值了 */// 缺点就是没有了双向绑定的便利性了// let val = event.target.value.trim();let val = event.trim();// 只能是正整数或空,可根据需求修改正则// item = e.target.value.replace(/[^\d]/g,'')if (/^[1-9]\d*$|^$/.test(val)) {this.oldInputNum = val;} else {// event.target.value = this.oldInputNum;event = this.oldInputNum;}},},
};
</script>
<style lang="scss" scoped>
</style>
最后试用了老项目里的代码方法 , 直接在 输入框上写 oninput 事件
<el-inputoninput="this.value=this.value.replace(/\D/g,'')"onafterpaste="this.value=this.value.replace(/\D/g,'')"></el-input>
但是此方法不知为何 , 用户在输入完一些数字之后 , 再输入汉字时 , 可能会将所输入的数字删除掉 , 可能是正则的 replace 导致的 , 因此这可能会影响到 v-model 的正常取值
只能通过获取用户最后一次输入的值赋值给 v-model 绑定的值了
<template><div><!-- 数字类型输入框 --><el-inputv-if="item.quInputType === '3'"size="small":maxlength="item.numDigit"v-model.number="item.numValue"oninput="this.value=this.value.replace(/\D/g,'')"@change="handleNumInput($event, item)"placeholder="请输入数字"></el-input></div>
</template><script>
export default {data() {return {// 在 item 中的数据字段numValue: "", // 数字输入框的绑定值quInputType: "1", // input 类型 : 1.文本 2.日期 3.数字modelValue: "", // 默认文本域绑定值answerInputWidth: "300", // input 宽度answerInputRow: "1", // input 高度dateValue: "", // 日期选择器绑定值numValue: "", // 数字输入框绑定值numDigit: "1", // 控制数字位数};},methods: {handleNumInput(event, item) {// 为了防止 v-model 失效 , 只好将最后一次输入的值赋值给绑定值了item.numValue = event;},},
};
</script><style lang="scss" scoped>
</style>
另外的一些解决思路及存在问题 :
Input 输入框
通过鼠标或键盘输入字符
基础用法
需求 :输入框限制用户只能输入数字
这个问题我使用过很多办法, 每一种都去尝试,但是结果都不太理想
比如以下的几种方法注:我要的效果是,输入框内只可输入数字,除了数字其他什么都不可输入,
包括标点符号,英文在内
第一种、使用 el-input 原生自带的 type=“number”
- 存在的问题
- type="number" 允许输入 e
- maxlength 属性会不生效
- 可以输入1.1.....11...1
第二种、使用 oninput
<el-inputv-model='inputValue'oninput="value=value.replace(/[^\d]/g,'')"maxLength='9' />
- 存在的问题
测试的时候偶然发现,有时候会出现输入框的值没有绑定到 v-model 上
暂时不知道原因,也比较难复现,而且输入汉字时数字可能会被删除
绑定的 @input 事件 , 有时会失效 , 暂时不知原因。
第三种、使用 onkeypress
<el-inputv-model="length" :maxlength="3" placeholder="长 cm" onkeypress='return( /[\d]/.test(String.fromCharCode(event.keyCode)))' />
- 存在的问题
这个代码一开始可以输中文 , 只有输数字时才不可以输入其他
第四种、使用 onafterpaste
<el-inputv-model='inputValue'onafterpaste="this.value=this.value.replace(/[\D]/g,'')"maxLength='9' />
- 存在的问题
- @input 绑定的 input 输入事件 , 会获取到你输入的最后一个非数字内容
第五种、监听 v-model 绑定值
侧面解决方案 :
利用 form 表单自带的校验功能
ElementUI - Form 表单 - 数字类型验证
缺点 : 不会限制用户输入非数字内容 , 只是会给警告提示 , 达不到预期需求效果
<el-form :model="numberValidateForm" ref="numberValidateForm" label-width="100px" class="demo-ruleForm"><el-form-itemlabel="年龄"prop="age":rules="[{ required: true, message: '年龄不能为空'},{ type: 'number', message: '年龄必须为数字值'}]"><el-input type="age" v-model.number="numberValidateForm.age" autocomplete="off"></el-input></el-form-item><el-form-item><el-button type="primary" @click="submitForm('numberValidateForm')">提交</el-button><el-button @click="resetForm('numberValidateForm')">重置</el-button></el-form-item> </el-form> <script>export default {data() {return {numberValidateForm: {age: ''}};},methods: {submitForm(formName) {this.$refs[formName].validate((valid) => {if (valid) {alert('submit!');} else {console.log('error submit!!');return false;}});},resetForm(formName) {this.$refs[formName].resetFields();}}} </script>
解决方案 :
试验了两天时间 , 才搞出来了自我感觉良好的效果 :(查阅各种资料 , 综合总结)
" ^[0-9]*[1-9][0-9]*$ " //正整数
上代码 , 自行体会哦
<template><div class="formBox"><!-- 阻止回车提交行为 --><el-form label-position="top" @submit.native.prevent><el-form-item size="mini"><!-- 文本类型输入框 --><el-inputv-if="item.quInputType === '1'"v-model="item.modelValue"type="textarea":style="`width:${item.answerInputWidth}px`":rows="item.answerInputRow"placeholder="请输入文本内容"></el-input><!-- 日期类型输入框 --><el-date-pickerv-if="item.quInputType === '2'":readonly="true"v-model="item.dateValue"type="date"placeholder="请选择日期"></el-date-picker><!-- 数字类型输入框 --><el-inputv-if="item.quInputType === '3'"size="small":maxlength="item.numDigit"v-model.number="item.numValue"@input="handleNumInput($event, item)"placeholder="请输入正整数"></el-input></el-form-item></el-form></div> </template> <script> export default {data() {return {// 在 item 中的数据字段numValue: "", // 数字输入框的绑定值quInputType: "1", // input 类型 : 1.文本 2.日期 3.数字modelValue: "", // 默认文本域绑定值answerInputWidth: "300", // input 宽度answerInputRow: "1", // input 高度dateValue: "", // 日期选择器绑定值numValue: "", // 数字输入框绑定值numDigit: "1", // 控制数字位数};},methods: {handleNumInput(event, item) {if (!/^[0-9]*[1-9][0-9]*$/.test(event)) {// 如果是非数字内容则 replace 切除掉item.numValue = event.replace(/\D/g, "");}},}, }; </script> <style lang="scss" scoped> </style>
实现数字框封装使用
开始封装 :
<!-- 作者 : 小灰狼功能 : 数字框时间 : 2022/04 --> <template><div><el-inputv-if="inputShow":readonly="readonly":disabled="disabled":size="inputSize":style="inputStyle":maxlength="maxlength":placeholder="placeholder"v-model="modelValue.val"@input="handleNumInput($event, modelValue.val)"></el-input></div> </template><script> // 导入数字型输入框封装函数 import { digitalInput } from "../../utils/digitalInput";export default {name: "numInput",props: {inputShow: {// 控制是否显示数字框type: Boolean,required: true,default: false,},readonly: {// 控制数字框是否只读type: Boolean,required: true,default: false,},disabled: {// 控制数字框是否禁用type: Boolean,default: false,},inputSize: {// 控制数字框大小type: String,required: true,default: "small",},inputStyle: {// 控制数字框样式type: Object,required: true,default: {},},maxlength: {// 控制数字框内容长度type: String,required: true,default: "1",},placeholder: {// 数字框提示文本type: String,required: true,default: "正整数",},modelValue: {// 数字框绑定值// type: Object,required: true,default: {},},},methods: {handleNumInput(event, val) {// 限制用户输入非数字内容this.modelValue.val = digitalInput(event, val);// this.$emit("handleNumInput", digitalInput(event, val));},}, }; </script><style lang="scss" scoped> </style>
digitalInput.js 文件
/** 数字型输入框* @param {} event 事件对象* @param {} modelValue 输入框绑定值* @return {} 处理好的内容*/ // 限制用户只能输入数字 export const digitalInput = (event, modelValue) => {// 限制用户输入非数字内容if (!/^[0-9]*[1-9][0-9]*$/.test(event)) {modelValue = event.replace(/\D/g, "");}console.log(modelValue, "封装函数");return modelValue; };
开始使用 :
<template><div><!-- 数字框组件 --><num-input:inputShow="quInputType === '3'":readonly="false":inputSize="'small'":inputStyle="{ width: '300px' }":maxlength="numlength":placeholder="'请输入正整数'":modelValue="modelValue"></num-input></div> </template><script> // 导入数字框组件 import numInput from "../../../components/common/numInput.vue";export default {name: "container",components: {numInput, // 数字框组件},data() {return {quInputType: "3", // 类型numlength: "1", // 控制数字位数modelValue: {val: "1",},};},methods: {}, }; </script>
UI组件库Form表单_数字类型验证之坑实现数字框相关推荐
- 获取form表单_【第1535期】前端 Form 的表单的一个通用解决方案
前言 今日早读文章由阿里@布达投稿分享. @布达,Alibaba Fusion项目组的.花名潕量.主要专注在设计系统.组件.可视化搭建这个领域 正文从这开始-- Fusion Next - Form ...
- Element Ui使用技巧——Form表单的校验规则rules详细说明;element的 form 表单rules详细用法
本文章是在项目开发时遇到问题看到的一片好文, 摘录自[博客园]–[逍遥云天]. 感谢作者 地址 – https://www.cnblogs.com/xyyt/p/13366812.html 在 [逍遥 ...
- Form表单提交与Validform验证的那些事
不管是做登录.注册还是实体的添加.修改,我们都会用到表单,并且也会同时用到验证,这里结合Validform验证来详细说明form表单提交的内情.. 1. 引入文件 <link href=&quo ...
- form表单input file类型的重置
我们知道form表单的dom中有一个reset方法,通过 document.getelemetbyid('yourform').reset()可以重置表单. Jquery对象没有reset方法,所以j ...
- Ant Design of Vue +TS 表单动态增加数据验证卧坑姿势
文章目录 Update 20210601 Update 20210525 原文: 1.a-form的model 2.获取数据 源码 Update 20210601 今天做别的页面的时候发现又取不到数据 ...
- antd如何获取表单的值_antd 父组件获取子组件中form表单的值
还是拿代码来讲吧,详情见注释 子组件 import React, { Component } from 'react'; import { Form, Input } from 'antd'; con ...
- 基于vue3的京东nutui组件库的表单校验规则:怎样进行表单验证?怎样只使用指定的某一个规则进行校验呢?
官网: NutUI - 移动端 Vue2.Vue3.小程序 组件库京东风格的轻量级移动端 Vue.React 组件库https://nutui.jd.com/#/component/form 用法: ...
- 关于Form表单的提交与验证???
<html> <head> <title>多媒体实验</title> <!--<link href="css/style ...
- angular js创建表单_如何优雅的使用 Angular 表单验证
随便说说,这一节可以跳过 去年参加 ngChine 2018 杭州开发者大会的时候记得有人问我: Worktile 是什么时候开始使用 Angular 的,我说是今年(2018年) 3 月份开始在新模 ...
最新文章
- Spring Cloud云服务架构 - common-service 项目构建过程
- Oracle客户端安装教程
- 从老赖们“维权”,看拍拍贷的底色
- thymeleaf的具体语法
- jsplumb dom 位置发生变化,连线错位
- java setsize_Java Vector setSize()方法与示例
- 输出前k大的数(信息学奥赛一本通-T1235)
- linux nginx权限配置文件,linux下nginx部署以及配置详解
- 国内外3D视觉优秀的实验室或者团队汇总
- python二级考试答案错误_如果name = “全国计算机等级考试二级Python”,以下选项中输出错误的是...
- 基于单片机的电子秤系统设计(电路+流程)
- SLM4054独立线性锂电池充电器的芯片的学习
- can网络管理(osek中的NM)
- iOS-Runtime之SEL、IMP、Method
- cs61c笔记-Lecture6 floating points浮点数
- Invalid classes inferred from unique values of `y`. Expected: [0 1 2], got [1 2 3]
- 找出m到n水仙花数c语言程序设计,《C语言课程设计输出水仙花数》.doc
- Evil Corp 团伙开始使用 LockBit Ransomware 逃避制裁
- 2022.10.14每日刷题打卡
- ZYNQ启动流程之分析BootRoM