【vue2父组件调用子组件方法之slot的使用】

父组件调用子组件方法之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>&nbsp;
      <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>

示例:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值