vue+element 表单验证问题

常规表单验证、自定义表单验证、动态增删表单验证

data() {
  var checkAge = (rule, value, callback) => {
    if (!value) {
      return callback(new Error('年龄不能为空'));
    }
    setTimeout(() => {
      if (!Number.isInteger(value)) {
        callback(new Error('请输入数字值'));
      } else {
        if (value < 18) {
          callback(new Error('必须年满18岁'));
        } else {
          callback();
        }
      }
    }, 1000);
  };
  return {
    rules = {
      name:[{
        required: true, message: '请输入标题', trigger: 'blur'
      }],
      url:[{
        pattern:
          /(http|ftp|https):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&amp;:/~\+#]*[\w\-\@?^=%&amp;/~\+#])?/,
        message: '请输入正确的链接地址',
        trigger: 'blur'
      }],
      age:[{
        validator: checkAge, trigger: 'blur'
      }]
    }
  }
}
1.常规表单验证
image.png
<el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm">
    <el-form-item label="活动名称" prop="name">
        <el-input v-model="ruleForm.name"></el-input>
    </el-form-item>
    <el-form-item label="活动区域" prop="region">
        <el-select v-model="ruleForm.region" placeholder="请选择活动区域">
            <el-option label="区域一" value="shanghai"></el-option>
            <el-option label="区域二" value="beijing"></el-option>
        </el-select>
    </el-form-item>
    <el-form-item label="活动时间" required>
        <el-col :span="11">
            <el-form-item prop="date1">
                <el-date-picker type="date" placeholder="选择日期" v-model="ruleForm.date1" style="width: 100%;"></el-date-picker>
            </el-form-item>
        </el-col>
        <el-col class="line" :span="2">-</el-col>
        <el-col :span="11">
            <el-form-item prop="date2">
                <el-time-picker placeholder="选择时间" v-model="ruleForm.date2" style="width: 100%;"></el-time-picker>
            </el-form-item>
        </el-col>
    </el-form-item>
    <el-form-item label="即时配送" prop="delivery">
        <el-switch v-model="ruleForm.delivery"></el-switch>
    </el-form-item>
    <el-form-item label="活动性质" prop="type">
        <el-checkbox-group v-model="ruleForm.type">
            <el-checkbox label="美食/餐厅线上活动" name="type"></el-checkbox>
            <el-checkbox label="地推活动" name="type"></el-checkbox>
            <el-checkbox label="线下主题活动" name="type"></el-checkbox>
            <el-checkbox label="单纯品牌曝光" name="type"></el-checkbox>
        </el-checkbox-group>
    </el-form-item>
    <el-form-item label="特殊资源" prop="resource">
        <el-radio-group v-model="ruleForm.resource">
            <el-radio label="线上品牌商赞助"></el-radio>
            <el-radio label="线下场地免费"></el-radio>
        </el-radio-group>
    </el-form-item>
    <el-form-item label="活动形式" prop="desc">
        <el-input type="textarea" v-model="ruleForm.desc"></el-input>
    </el-form-item>
    <el-form-item>
        <el-button type="primary" @click="submitForm('ruleForm')">立即创建</el-button>
        <el-button @click="resetForm('ruleForm')">重置</el-button>
    </el-form-item>
</el-form>
<script>
export default {
    data() {
    return {
        ruleForm: {
        name: '',
        region: '',
        date1: '',
        date2: '',
        delivery: false,
        type: [],
        resource: '',
        desc: ''
        },
        rules: {
            name: [
                { required: true, message: '请输入活动名称', trigger: 'blur' },
                { min: 3, max: 5, message: '长度在 3 到 5 个字符', trigger: 'blur' }
            ],
            region: [
                { required: true, message: '请选择活动区域', trigger: 'change' }
            ],
            date1: [
                { type: 'date', required: true, message: '请选择日期', trigger: 'change' }
            ],
            date2: [
                { type: 'date', required: true, message: '请选择时间', trigger: 'change' }
            ],
            type: [
                { type: 'array', required: true, message: '请至少选择一个活动性质', trigger: 'change' }
            ],
            resource: [
                { required: true, message: '请选择活动资源', trigger: 'change' }
            ],
            desc: [
                { required: true, message: '请填写活动形式', trigger: 'blur' }
            ]
        }
    };
    },
    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>
2.自定义表单验证
image.png
<el-form :model="ruleForm" status-icon :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm">
    <el-form-item label="密码" prop="pass">
        <el-input type="password" v-model="ruleForm.pass" autocomplete="off"></el-input>
    </el-form-item>
    <el-form-item label="确认密码" prop="checkPass">
        <el-input type="password" v-model="ruleForm.checkPass" autocomplete="off"></el-input>
    </el-form-item>
    <el-form-item label="年龄" prop="age">
        <el-input v-model.number="ruleForm.age"></el-input>
    </el-form-item>
    <el-form-item>
        <el-button type="primary" @click="submitForm('ruleForm')">提交</el-button>
        <el-button @click="resetForm('ruleForm')">重置</el-button>
    </el-form-item>
</el-form>
<script>
export default {
    data() {
        var checkAge = (rule, value, callback) => {
            if (!value) {
                return callback(new Error('年龄不能为空'));
            }
            setTimeout(() => {
                if (!Number.isInteger(value)) {
                    callback(new Error('请输入数字值'));
                } else {
                    if (value < 18) {
                        callback(new Error('必须年满18岁'));
                    } else {
                        callback();
                    }
                }
            }, 1000);
        };
        var validatePass = (rule, value, callback) => {
            if (value === '') {
                callback(new Error('请输入密码'));
            } else {
                if (this.ruleForm.checkPass !== '') {
                    this.$refs.ruleForm.validateField('checkPass');
                }
                callback();
            }
        };
        var validatePass2 = (rule, value, callback) => {
            if (value === '') {
                callback(new Error('请再次输入密码'));
            } else if (value !== this.ruleForm.pass) {
                callback(new Error('两次输入密码不一致!'));
            } else {
                callback();
            }
        };
        return {
            ruleForm: {
                pass: '',
                checkPass: '',
                age: ''
            },
            rules: {
                pass: [
                    { validator: validatePass, trigger: 'blur' }
                ],
                checkPass: [
                    { validator: validatePass2, trigger: 'blur' }
                ],
                age: [
                    { validator: checkAge, trigger: 'blur' }
                ]
            }
        };
    },
    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>
3.动态增减

a.表单


image.png
<el-form :model="storeForm" :rules="rules" ref="storeForm" label-width="100px">
    <el-form-item label="联系电话:" required>
        <el-row :gutter="20" class="tel-wrapper">
            <el-col :span="6" v-for="(contact,index) in storeForm.storeContacts" :key="contact.id">
                <el-form-item :prop="'storeContacts.' + index+ '.mobile'" :rules="rules.mobile">
                    <el-input v-model="contact.mobile" type="number">
                        <el-button slot="append" :icon="index == 0 ? 'el-icon-plus' : 'el-icon-delete'" @click="telInputHandler(index)"></el-button>
                    </el-input>
                </el-form-item>
            </el-col>
        </el-row>
    </el-form-item>
    <el-form-item>
        <el-button type="primary" @click="submitForm('storeForm')">提交</el-button>
        <el-button @click="resetForm('storeForm')">重置</el-button>
    </el-form-item>
</el-form>
<script>
import { isMobile } from '@/util/validate'
export default {
    data() {
        return {
            storeForm: {
                storeContacts: []
            },
            rules: {
                mobile: { validator: mobile, trigger: 'blur' }
            }
        };
    },
    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>
// util/validate.js
export function isMobile (rule:any, value:any, callback:any) {
    if (!value) {
        callback(new Error('请输入手机号'))
    } else {
        if (!(/^1[3456789]\d{9}$/.test(value))) {
            callback(new Error('手机号码有误'))
        } else {
            callback()
        }
    }
}

b.表格


image.png
<el-form ref="cardForm" :model="cardForm" :rules="rules">
    <el-row>
        <el-col :span="12">
            <el-form-item label="会员卡名称:" prop="name" label-width="125px">
                <el-input
                    v-model="cardForm.name"
                    autocomplete="off"
                    maxlength="30"
                    placeholder="输入会员卡名称"
                ></el-input>
            </el-form-item>
        </el-col>
        <el-col :span="12">
            <el-form-item label="售价:" prop="price" label-width="125px">
                <el-input v-model="cardForm.price" autocomplete="off" type="number" min="0" max="99999">
                    <template slot="append">元</template>
                </el-input>
            </el-form-item>
        </el-col>
    </el-row>
    <div style="margin-top:7px">
        <p class="sub-title">会员卡内容</p>
        <el-table
            border
            :data="cardForm.contents"
            tooltip-effect="dark"
            style="width: 100%"
            max-height="150"
            class="mb-10"
        >
            <el-table-column label="类型" align="center">
                <template slot-scope="scope">
                    <el-form-item :prop="'contents.' + scope.$index + '.type'" :rules="rules.type">
                        <el-select
                            v-model="scope.row.type"
                            placeholder="请选择"
                            @change="typeChanged($event,scope.row)"
                        >
                            <el-option
                                v-for="item in categoryOptions"
                                :key="item.value"
                                :label="item.label"
                                :value="item.value"
                            ></el-option>
                        </el-select>
                    </el-form-item>
                </template>
            </el-table-column>
            <el-table-column label="内容" align="center">
                <template slot-scope="scope">
                    <span v-if="scope.row.type == 5">现金</span>
                    <el-form-item
                        v-if="scope.row.type == 1"
                        :prop="'contents.' + scope.$index + '.itemId'"
                        :rules="rules.project"
                    >
                        <el-select
                            v-model="scope.row.itemId"
                            filterable
                            placeholder="请选择项目"
                            @change="nameChanged($event,scope.row)"
                        >
                            <el-option
                                v-for="item in projectList"
                                :key="item.id"
                                :label="item.name"
                                :value="item.id"
                            ></el-option>
                        </el-select>
                    </el-form-item>
                </template>
            </el-table-column>
            <el-table-column label="数量/金额" align="center">
                <template slot-scope="scope">
                    <el-form-item :prop="'contents.' + scope.$index + '.amount'" :rules="rules.amount">
                        <el-input v-model="scope.row.amount"></el-input>
                    </el-form-item>
                </template>
            </el-table-column>
            <el-table-column label="操作" align="center">
                <template slot-scope="scope">
                    <el-button type="text" icon="el-icon-delete" @click="delRow(scope.row)"></el-button>
                </template>
            </el-table-column>
        </el-table>
        <el-button class="add-btn" icon="el-icon-plus" @click="addRow()">继续添加</el-button>
    </div>
    <el-form-item>
        <el-button type="primary" @click="submitForm('cardForm')">提交</el-button>
        <el-button @click="resetForm('cardForm')">重置</el-button>
    </el-form-item>
</el-form>
<script>
import { isMobile } from '@/util/validate'
export default {
    data() {
        return {
            cardForm: {
                name: '',
                price: '',
                contents: [{}]
            },
            rules: {
                name: { required: true, message: "请输入会员卡名称", trigger: "blur" },
                price: { required: true, message: "请输入售价", trigger: "blur" },
                type: { required: true, message: "请选择类型", trigger: "blur" },
                project: { required: true, message: "请选择项目", trigger: "blur" },
                amount: { required: true, message: "请输入数量", trigger: "blur" }
            }
        };
    },
    methods: {
        addRow () {
            let item: any = {}
            this.cardForm.contents.push(item)
        }
       delRow (row: any) {
            let tableData = this.cardForm.contents
            if (tableData.length === 1) {
                return
            }
            for (var i = 0; i < tableData.length; i++) {
                if (tableData[i] === row) {
                    tableData.splice(i, 1)
                }
            }
        }
        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>
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,546评论 6 507
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,224评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,911评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,737评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,753评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,598评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,338评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,249评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,696评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,888评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,013评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,731评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,348评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,929评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,048评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,203评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,960评论 2 355

推荐阅读更多精彩内容

  • 专业考题类型管理运行工作负责人一般作业考题内容选项A选项B选项C选项D选项E选项F正确答案 变电单选GYSZ本规程...
    小白兔去钓鱼阅读 8,994评论 0 13
  • 最后我因为过失伤人被判处有期徒刑七年。我坐牢了!这个我们医院盛传的最有前途的下一代~~~ 老六带着我爸妈来看我,一...
    刘喆_0067阅读 77评论 0 1
  • “努力不是一场意志力的较量,而是一种需要学习的策略。” 我觉得努力应该是一场中后期阶段的意志力较量。虽然说选择重于...
    枫易晚阅读 341评论 0 1
  • 一 昨天是南京大屠杀惨案80周年纪念日,在南京大屠杀江东门纪念馆祭奠广场举行了庄严的国家公祭仪式 不知道是不是那3...
    疯岩疯语sun阅读 303评论 0 0
  • jmeter中的事务控制器相当于loadrunner中的事务,即可以把多个请求看成一个整体,统计响应时间、TPS等...
    雪人来也阅读 1,144评论 0 0