父组件调用子组件方法之slot的使用
具体功能需求:
一个页面,点击按钮,打开一个弹窗。弹窗有自定义表单和公共表单,提交的时候要获取两个表单的数据以及复显表单数据
为什么使用插槽了,因为我需要在弹窗中复用公共表单,而自定义表单是不固定的,所以需要动态加载。
1、 实现方式 直接通过插槽的 this.$slots 来获取子组件的方法
注意:使用的ui组件库是iview
页面 index.vue
<template >
<div>
<Button type="primary" @click="handleOpen">打开弹窗 </Button>
<FormModal :modalVisibleProp.sync="modalVisibleProp">
<template slot="customForm">
<FormCustom />
</template>
</FormModal>
</div>
</template>
<script>
import FormModal from './FormModal.vue';
import FormCustom from './FormCustom.vue';
export default {
name: '',
components: {
FormModal,
FormCustom
},
data() {
return {
modalVisibleProp: false
};
},
methods: {
// 新增
handleOpen() {
this.modalVisibleProp = true;
}
}
};
</script>
弹窗组件 FormModal.vue
<template>
<Modal v-model="visible" title="测试" width="40" @on-visible-change="onVisibleChange" @on-cancel="handleReset">
<div>
<slot name="customForm"></slot>
<FormCommon ref="commonForm" />
</div>
<div class="drawer-footer">
<Button @click="handleReset">取消</Button>
<Button type="primary" :loading="modalLoading" @click="ok">提交</Button>
</div>
</Modal>
</template>
<script>
import FormCommon from './FormCommon.vue';
export default {
name: 'FormModal',
components: {
FormCommon
},
props: {
modalVisibleProp: {
type: Boolean,
default: false
}
},
data() {
return {};
},
computed: {
visible: {
get: function () {
return this.modalVisibleProp;
},
set: function () {}
}
},
methods: {
async ok() {
try {
let customFormValue = {};
const customFormInstance = this.$slots.customForm[0].componentInstance;
if (customFormInstance && typeof customFormInstance.getData === 'function') {
customFormValue = await customFormInstance.getData(); // 自定义表单获取数据
}
const commonFormValue = await this.$refs.commonForm.getData(); // 公共表单获取数据
} catch (error) {
console.log(error);
}
},
handleReset() {
this.$emit('update:modalVisibleProp', false);
},
onVisibleChange(visible) {
if (!visible) {
this.handleReset();
}
}
}
};
</script>
自定义表单 FormCustom.vue
<template>
<Form ref="form" :model="formItem" :rules="formItemRules" :label-width="135">
<FormItem label="custom" prop="a">
<Input v-model="formItem.a" placeholder="请输入内容"> </Input>
</FormItem>
</Form>
</template>
<script>
export default {
name: '',
data() {
return {
formItem: {
a: 'customData'
},
formItemRules: {
a: [{ required: true, message: '不能为空' }]
}
};
},
methods: {
async getData() {
const valid = await this.$refs.form.validate();
if (valid) {
return this.formItem;
} else {
return false;
}
},
setData(data) {
this.formItem = data;
}
}
};
</script>
公共表单 FormCommon.vue
<template>
<Form ref="form" :model="formItem" :rules="formItemRules" :label-width="135">
<FormItem label="common" prop="b">
<Input v-model="formItem.b" placeholder="请输入内容"> </Input>
</FormItem>
</Form>
</template>
<script>
export default {
name: '',
data() {
return {
formItem: {
b: 'commonData'
},
formItemRules: {
b: [{ required: true, message: '不能为空' }]
}
};
},
methods: {
async getData() {
const valid = await this.$refs.form.validate();
if (valid) {
return this.formItem;
} else {
return false;
}
},
setData(data) {
this.formItem = data;
}
}
};
</script>
示例: