自己封装的自定义组件,想结合 form表单校验, 可参照如下示例
封装了一个 wap-input 组件, 期望组件能适当的触发 父组件的 form 的 表单校验, 和 el-form-item 一样效果
<template>
<div class="input-wrap-container">
<div class='label'>
<template v-if="label">{{label}}</template>
<slot name='label' v-else></slot>
</div>
<el-input v-model="val"
@input="onInput"
@change="onChange"
@blur="onBlur"
/>
</div>
</template>
<script>
import emitter from 'element-ui/src/mixins/emitter'
let { methods: { dispatch } } = emitter
export default {
name: 'input-wrap',
props: {
value: [String, null],
label: String
},
data () {
return {
val: ''
}
},
mounted () {
this.val = this.value
},
methods: {
onInput(val) {
this.$emit('input', val)
},
onChange () {
// el-form 组件中有对这个事件的监听
dispatch.call(this, 'ElFormItem', 'el.form.change', this.val)
},
onBlur () {
dispatch.call(this, 'ElFormItem', 'el.form.blur', this.val)
}
}
}
</script>
<style lang='less'>
.input-wrap-container {
display: flex;
align-items: center;
.label {
min-width: 60px;
margin-right: 12px;
}
}
</style>
手动触发 el.form.blur 或者 el.form.change 即可
父组件使用 , wrap-input 已经注册为全局组件了
<template>
<el-form ref="form" :model="form" :rules="rules">
<el-form-item label="对比" prop="name">
<el-input v-model="form.name"></el-input>
</el-form-item>
<el-form-item prop="age">
<wrap-input label="年龄" v-model="form.age"></wrap-input>
</el-form-item>
<div><el-button @click="checkData">提交校验</el-button></div>
</el-form>
</template>
<script>
export default {
data () {
return {
form: {
range3: [],
name: '',
age: ''
},
rules: {
name: [
{
type: 'string',
required: true,
message: '请输入姓名',
trigger: ["blur", "change"]
}
],
age: [
{
type: 'string',
required: true,
message: '请输入年龄',
trigger: ["blur", "change"]
}
]
}
}
},
methods: {
checkData () {
this.$refs['form'].validate((valid, f) => {
console.log("valid 校验是否通过", valid)
console.log(`不通过的字段`)
console.log(f)
})
},
}
}
</script>
从 element-ui 源码中得知, 父组件是监听了这2个事件的, 只要手动触发即可
为什么子组件能触发顶层组件的事件呢 ? 这就得看 dispatch 的实现了
dispatch 中 一直找 父组件,只要匹配到父组件的 name 和 ElFormItem 字符串相同, 就直接触发 el.form.blur 事件