一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第1天,点击查看活动详情。(juejin.cn/post/705288… "juejin.cn/post/705288…
[Vue warn]: Error in v-on handler: "TypeError: Cannot read property 'validate' o
这种报错是由于多层嵌套,prop 写错造成
一开始直接复制了element ui 上的模板没有修改 报错
小demo:
data:
dataInfo: {
dynamicValidateForm: [
{
domains: [
{
value: "",
name: ""
}
]
}
]
}
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();
},
removeDomain(item) {
// 先找到在删除
var index = this.dataInfo.dynamicValidateForm[0].domains.indexOf(item);
if (index !== -1) {
this.dataInfo.dynamicValidateForm[0].domains.splice(index, 1);
}
},
addDomain() {
this.dataInfo.dynamicValidateForm[0].domains.push({
value: "",
name: ""
});
}
html:
<template>
<div class="wrap">
<el-form
:model="dataInfo"
ref="dynamicValidateForm"
label-width="100px"
class="demo-dynamic"
>
<div v-for="(item, index) in dataInfo.dynamicValidateForm" :key="index">
<div v-for="(domain, idx) in item.domains" :key="idx">
<el-row class="father">
<el-col :span="6">
<el-form-item
:label="'域名' + index"
:prop="
'dynamicValidateForm.' + index + '.domains.' + idx + '.name'
"
:rules="{
required: true,
message: '域名不能为空',
trigger: 'blur'
}"
>
<el-input v-model="domain.name"></el-input>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item
:label="'name' + index"
:prop="
'dynamicValidateForm.' + index + '.domains.' + idx + '.value'
"
:rules="{
required: true,
message: 'name不能为空',
trigger: 'blur'
}"
>
<el-input v-model="domain.value"></el-input>
<el-button class="btn" @click.prevent="removeDomain(domain)"
>删除</el-button
>
</el-form-item>
</el-col>
</el-row>
</div>
</div>
<el-form-item>
<el-button type="primary" @click="submitForm('dynamicValidateForm')"
>提交</el-button
>
<el-button @click="addDomain">新增域名</el-button>
<el-button @click="resetForm('dynamicValidateForm')">重置</el-button>
</el-form-item>
</el-form>
</div>
</template>
样式:
<style lang="scss" scoped>
.wrap{
padding-top: 20px;
width: 1300px;
margin-top: 200px;
margin-left: 200px;
border-radius: 10px;
background-color: aliceblue;
border: 1px solid aqua;
}
.father{
position: relative;
}
.btn{
position: absolute;
right: -160px;
}
</style>
关键:
要注意每个层级的index
注意:
1.特别注意 prop 和 rules 的绑定, prop 里面的名称必须和输入框绑定的属性名称对应起来。 2. dattInfo 必须是一个对象,循环的是对象里面的 list 数组,往 list 数组里面动态增加数据。 3. 循环体里面再次添加动态的表单时,注意 idx 和外层 index 的区别。
源码:
<template>
<div class="wrap">
<el-form
:model="dataInfo"
ref="dynamicValidateForm"
label-width="100px"
class="demo-dynamic"
>
<div v-for="(item, index) in dataInfo.dynamicValidateForm" :key="index">
<div v-for="(domain, idx) in item.domains" :key="idx">
<el-row class="father">
<el-col :span="6">
<el-form-item
:label="'域名' + index"
:prop="
'dynamicValidateForm.' + index + '.domains.' + idx + '.name'
"
:rules="{
required: true,
message: '域名不能为空',
trigger: 'blur'
}"
>
<el-input v-model="domain.name"></el-input>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item
:label="'name' + index"
:prop="
'dynamicValidateForm.' + index + '.domains.' + idx + '.value'
"
:rules="{
required: true,
message: 'name不能为空',
trigger: 'blur'
}"
>
<el-input v-model="domain.value"></el-input>
<el-button class="btn" @click.prevent="removeDomain(domain)"
>删除</el-button
>
</el-form-item>
</el-col>
</el-row>
</div>
</div>
<el-form-item>
<el-button type="primary" @click="submitForm('dynamicValidateForm')"
>提交</el-button
>
<el-button @click="addDomain">新增域名</el-button>
<el-button @click="resetForm('dynamicValidateForm')">重置</el-button>
</el-form-item>
</el-form>
</div>
</template>
<script>
export default {
name: "",
created() {},
mounted() {},
data() {
return {
// dynamicValidateForm: {
// obj:{
// domains: [
// {
// value: "",
// name:""
// }
// ]
// },
// email: ""
// },
// dynamicValidateForm: {
// domains: [
// {
// value: "",
// name:""
// }
// ],
// email: ""
// }
// dynamicValidateForm: {
// domains: [
// {
// value: "",
// name:""
// }
// ],
// email: ""
// }
dataInfo: {
dynamicValidateForm: [
{
domains: [
{
value: "",
name: ""
}
]
}
]
}
};
},
computed: {},
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();
},
removeDomain(item) {
// 先找到在删除
var index = this.dataInfo.dynamicValidateForm[0].domains.indexOf(item);
if (index !== -1) {
this.dataInfo.dynamicValidateForm[0].domains.splice(index, 1);
}
},
addDomain() {
this.dataInfo.dynamicValidateForm[0].domains.push({
value: "",
name: ""
});
}
}
};
</script>
<style lang="scss" scoped>
.wrap{
padding-top: 20px;
width: 1300px;
margin-top: 200px;
margin-left: 200px;
border-radius: 10px;
background-color: aliceblue;
border: 1px solid aqua;
}
.father{
position: relative;
}
.btn{
position: absolute;
right: -160px;
}
</style>