父组件调用子组件方法之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>
示例: