写一个基本的嵌套组件demo,仿照ELement的form组件
做了以下小功能点:
- 包裹组件向被包裹组件传递参数
form
和rules
- 被包裹组件反向传递校验函数,包裹组件的
getCheck
获取被包裹组件的check
- 外部使用
validate
方法,进行两层组件的值校验
- 引用
<template>
<yys-father ref="Father" :form="form" :rules="rules">
<yys-children prop="name">
<input v-model="form.name" type="text" />
</yys-children>
<br />
<yys-children prop="sex">
<input v-model="form.sex" type="text" />
</yys-children>
<br />
<button @click="submit()">测试</button>
</yys-father>
</template>
<script>
import yysFather from '../components/yys-father.vue'
import yysChildren from '../components/yys-children.vue'
export default {
name: 'Home',
components: {
yysFather,
yysChildren
},
data() {
return {
form: {
name: '张三',
sex: '男'
},
rules: {
name: {
notNull: true
},
sex: {
notNull: false
}
}
}
},
methods: {
submit() {
this.$refs.Father.validate().then(res => {
console.log(200, res)
})
}
}
}
</script>
- 包裹组件
<template>
<div>
<h1>测试input</h1>
<slot />
</div>
</template>
<script>
export default {
props: {
form: {
type: Object,
default: () => {
}
},
rules: {
type: Object,
default: () => {
}
}
},
provide() {
return {
formData: this.form,
rulesData: this.rules,
getCheck: cb => {
this.checkList.push(cb)
}
}
},
data: () => {
return {
// 校验列表
checkList: []
}
},
methods: {
validate() {
return new Promise((resolve, reject) => {
try {
let boo = true
this.checkList.forEach(e => {
const _b = e()
if (_b) boo = false
})
if (boo) {
alert('有必填项未填')
} else {
alert('可以提交')
}
resolve(boo)
} catch (err) {
reject(err)
}
})
}
}
}
</script>
- 被包裹组件
<template>
<div>
<span style="color:red">{
{ '*' }}</span>
<slot />
<span>{
{ showText ? text : null }}</span>
</div>
</template>
<script>
export default {
inject: ['formData', 'rulesData', 'getCheck'],
props: {
prop: {
type: String,
default: ''
},
text: {
type: String,
default: '请填写'
}
},
data: () => {
return {
showText: false
}
},
created() {
if (this.rulesData[this.prop]) {
if (this.rulesData[this.prop].notNull) {
// 将当前行校验上报
this.getCheck(() => this.check())
}
}
},
methods: {
check() {
if (!this.formData[this.prop]) {
this.showText = true
return false
}
this.showText = false
return true
}
}
}
</script>