模态框公共组件

212 阅读1分钟

适用于ele,antd,arco等公共组件库,vue3为技术框架

js版

import { nextTick, ref } from 'vue';
import useLoading from './loading';

export default ({ onOpen, onClose, onOk }) => {
  const val = ref();

  const visible = ref(false);
  const { loading, setLoading } = useLoading();

  const show = (value, secondVal, id) => {
    visible.value = true;
    nextTick(() => {
      onOpen && onOpen(value, secondVal, id);
    });
  };

  const hide = () => {
    visible.value = false;
    onClose && onClose();
  };

  function isPromiseLike(it) {
    return it instanceof Promise || typeof it.then === 'function';
  }

  const submit = (done) => {
    setLoading(true);

    try {
      setLoading(false);
      const isOk = onOk && onOk();

      if (isPromiseLike(isOk) && typeof isOk !== 'boolean') {
        isOk.then((ok) => {
          setLoading(false);

          return done(ok);
        });

        return;
      }

      setLoading(false);
      return done(!!isOk);
    } catch (e) {
      console.log(e);

      setLoading(false);
      return done && done(false);
    }
  };

  return {
    val,
    visible,
    loading,

    show,
    hide,
    submit,
  };
};

组件中使用

 import useModal from '@/hooks/modal';
 
  const { visible, show, hide, submit, loading } = useModal({
    async onOpen(type, val) {
      modalType.value = type;
      if (type === 'add') {
        const data = cloneDeep(defaultForm());
        setForm(data);
      } else {
        const data = cloneDeep(val || defaultForm());
        setForm(data);
      }
    },
    async onOk() {
      const isOk = await submitForm();
      return !!isOk;
    },
  });

TS版

/* eslint-disable consistent-return */
import { ref } from 'vue';
import useLoading from './loading';

type modalParams = {
  onOpen?: any;
  onClose?: any;
  onOk?: () => Promise<boolean> | boolean;
};

export default ({ onOpen, onClose, onOk }: modalParams) => {
  const val = ref();

  const visible = ref(false);
  const { loading, setLoading } = useLoading();

  const show = (value?: any, secondVal?: any, id?: any) => {
    visible.value = true;

    onOpen && onOpen(value, secondVal, id);
  };

  const hide = () => {
    visible.value = false;
    onClose && onClose();
  };

  function isPromiseLike<T>(it: unknown): it is PromiseLike<T> {
    return it instanceof Promise || typeof (it as any)?.then === 'function';
  }

  const submit = (done: (closed: boolean) => void) => {
    setLoading(true);

    try {
      setLoading(false);
      const isOk = onOk && onOk();

      if (isPromiseLike<boolean>(isOk) && typeof isOk !== 'boolean') {
        isOk.then((ok: boolean) => {
          setLoading(false);

          return done(ok);
        });

        return;
      }

      setLoading(false);
      return done(!!isOk);
    } catch (e) {
      console.log(e);

      setLoading(false);
      return done && done(false);
    }
  };

  return {
    val,
    visible,
    loading,

    show,
    hide,
    submit,
  };
};

组件中使用

 import useModal from '@/hooks/modal';
 
const { visible, show, hide, submit, loading } = useModal({
  async onOpen(type: string, val: any) {
    modalType.value = type;
      if (type === 'add') {
        const data = cloneDeep(defaultForm());
        setForm(data);
      } else {
        const data = cloneDeep(val || defaultForm());
        setForm(data);
      }
  },
  async onOk() {
    const isOk = await submitForm();
    return !!isOk;
  },
});