element-ui & form ref bug All In One
element-ui & form ref bug All In One
<script src="//unpkg.com/vue/dist/vue.js"></script>
<script src="//unpkg.com/element-ui@2.15.2/lib/index.js"></script>
<h1>"[Vue warn]: Error in v-on handler: 'TypeError: Cannot read property 'validate' of undefined'</h1>
<hr>
<div id="app">
<!-- ref="ruleForm" -->
<el-form :model="ruleForm" :rules="rules" ref="ruleFormBug" 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>
<!-- 为什么要在 DOM 上使用 validator: validateDesc,才可以 ??? -->
<el-form-item
:rules="[
{
message: '请填写活动形式',
trigger: 'blur',
validator: validateDesc,
},
]"
label="活动形式"
prop="desc">
<el-input
type="textarea"
v-model="ruleForm.desc"
placeholder="请输入"
@blur="descHandler"
@keyup.enter.native="descHandler">
</el-input>
</el-form-item>
<!-- <el-form-item
label="活动形式"
prop="desc">
<el-input
type="textarea"
v-model="ruleForm.desc"
placeholder="请输入"
@blur="descHandler"
@keyup.enter.native="descHandler">
</el-input>
</el-form-item> -->
<el-form-item>
<el-button type="primary" @click="submitForm('ruleFormBug')">立即创建</el-button>
<el-button @click="resetForm('ruleFormBug')">重置</el-button>
<!-- <el-button type="primary" @click="submitForm('ruleForm')">立即创建</el-button>
<el-button @click="resetForm('ruleForm')">重置</el-button> -->
</el-form-item>
</el-form>
</div>
var Main = {
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',
// validator: validateDesc,
// 为什么要在 DOM 上使用 validator: validateDesc,才可以 ???
}
]
}
};
// ✅ 自动表单校验只会校验 required: true 的字段
// 如果需要给,非 required 的字段,手动校验,需要写很多东西 , holy shit
// 手动触发 blur 校验,??? 非必填为什么要校验 ???
},
methods: {
validateDesc (rule, value, callback) {
// console.log('rule =', rule);
// console.log('value =', value);
// console.log('callback =', callback);
console.log('2. 显示表单校验结果,message');
if (this.errorMessage) {
callback(new Error(this.errorMessage));
} else {
callback();
// 自动校验, 没有 errorMessage ❌, test throw error
// callback(new Error('自动校验, 没有 errorMessage ❌'));
}
},
// 手动触发校验
descHandler () {
// 1. 同步代码,优先级最高
console.log('1. 手动触发校验 desc');
if(!this.ruleForm.desc) {
this.errorMessage = '请输入 Desc';
}
const key = 'desc';
this.validateFieldByKey(key);
},
validateFieldByKey (key = '') {
const formName = 'ruleFormBug';
if(key) {
this.$refs[formName].validateField(key);
}
},
async asyncValidateFiled () {
// 3. 异步代码,宏任务,优先级更低
setTimeout(() => {
console.log('3. delay 表单的异步校验,为 Async API 手动校验流出返回数据的时间');
}, 0);
return {};
},
async submitForm(formName = 'ruleFormBug') {
// 手动触发校验
this.descHandler();
// 手动触发 Asycn 校验
await this.asyncValidateFiled();
// delay async form validate
setTimeout(() => {
console.log('4. 异步代码,宏任务 ???');
}, 0);
// await this.$refs[formName].validate((valid) => {
// this.$refs[formName].validate((valid) => {
// if (valid) {
// alert('submit!');
// } else {
// // 2. 异步代码,微任务,优先级低
// console.log('2. error submit ❌');
// return false;
// }
// });
setTimeout(() => {
this.$refs[formName].validate((valid) => {
if (valid) {
alert('submit!');
} else {
// 5. 异步代码,宏任务嵌套微任务,优先级最低
console.log('5. error submit ❌');
return false;
}
});
}, 0);
},
resetForm(formName) {
this.$refs[formName].resetFields();
}
}
}
var Ctor = Vue.extend(Main)
new Ctor().$mount('#app')
refs
https://github.com/xgqfrms/vue/issues/165
https://codepen.io/xgqfrms/pen/rNyogpd?editors=1011
©xgqfrms 2012-2020
www.cnblogs.com/xgqfrms 发布文章使用:只允许注册用户才可以访问!
原创文章,版权所有©️xgqfrms, 禁止转载 🈲️,侵权必究⚠️!
本文首发于博客园,作者:xgqfrms,原文链接:https://www.cnblogs.com/xgqfrms/p/14888695.html
未经授权禁止转载,违者必究!