dialog函数式调用方法

实现页面不同层级内容解耦,使代码更清晰易维护。一个比较常见的场景是关闭表单时需要清空表单内容(element-ui dialog有个destroy-on-close属性,但是我使用时没有生效,也不知道为啥)。以element-ui dialog为例,其他库同理。

import Vue from 'vue';
import { Message } from 'element-ui';

/**
 * @param {Object} component - 组件,需定义handleSubmit方法,并在方法内执行$emit('submit',[params])
 * @param {string} title - dialog标题
 * @param {Object} props - 传递给组件的数据
 * @param {Function} submit - 点击确认的回调函数,参数为组件的handleSubmit函数中$emit参数
 */
export default function DialogCall(component, title, props, submit) {
  let instance;

  const VueClass = Vue.extend({
    data() {
      return {
        visible: false,
        loading: false,
      };
    },
    mounted() {
      this.visible = true;
    },
    render(h) {
      return h(
        'el-dialog',
        {
          props: { 'visible': this.visible, title, 'close-on-click-modal': false, 'close-on-press-escape': false },

          on: {
            'update:visible': (value) => {
              this.visible = value;
            },

            'closed': () => {
              instance.$el.remove();
              instance.$destroy();
            },
          },
        },
        [
          h(component, {
            props,
            on: {
              submit: async (event) => {
                if (typeof submit === 'function') {
                  this.loading = true;
                  const bool = await submit(event);
                  this.loading = false;
                  if (bool !== false) {
                    this.visible = false;
                  }
                } else {
                  Message.error('参数submit不是一个方法');
                }
              },
              
              close: ()=> (this.visible = false)
            },
            ref: 'content',
          }),
          h('template', { slot: 'footer' }, [
            h(
              'el-button',
              {
                props: { size: 'medium' },
                on: {
                  click: () => {
                    const callback = this.$refs.content.handleCancel;
                    if (typeof callback === 'function') {
                      callback();
                    } else {
                      this.visible = false;
                    }
                  },
                },
              },
              '取消'
            ),
            h(
              'el-button',
              {
                props: { size: 'medium', type: 'primary', loading: this.loading },
                on: {
                  click: () => {
                    const callback = this.$refs.content.handleSubmit;
                    if (typeof callback === 'function') {
                      callback();
                    } else {
                      Message.error('dialog默认插槽组件未定义handleSubmit方法');
                    }
                  },
                },
              },
              '确认'
            ),
          ]),
        ]
      );
    },
  });

  instance = new VueClass();
  const div = document.createElement('div');
  document.body.append(div);
  instance.$mount(div);
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值