使用函数调用组件

56 阅读1分钟

轻提示组件一般都会加静态方法调用的封装,以便于在任何代码位置都可以使用提示组件。

一些通用性展示组件可以借鉴这种方式,组件库里可以找到实现方式,代码如下(根据自身需求做一些调整)

import { createVNode, render as vueRender } from "vue";
import { Modal } from "ant-design-vue";

export function show({ children, modalProps = {}, callback }) {
  const container = document.createDocumentFragment();
  let modalIns = null;
  let closeFn = null;

  function destroy() {
    if (modalIns) {
      vueRender(null, container);
      modalIns = null;
    }
    closeFn?.();
  }

  function close() {
    update({
      open: false,
      afterClose: () => {
        destroy();
      },
    });
  }

  function update(props) {
    if (modalIns) {
      Object.assign(modalIns.component.props, props);
      modalIns.component.update();
    }
  }

  const Wrapper = (props, ctx) => {
    return <Modal {...props}>{ctx.slots?.default()}</Modal>;
  };

  function render(props, children) {
    const vm = createVNode(Wrapper, { ...props }, () => children);
    vueRender(vm, container);
    return vm;
  }

  const wrapClassName = modalProps?.wrapClassName
    ? `${modalProps?.wrapClassName}`
    : "x-preview-modal";

  modalIns = render(
    { open: true, onCancel: close, footer: null, ...modalProps, wrapClassName },
    children
  );
  closeFn = callback;
  return {
    destroy: close,
  };
}

// 图片预览
export function previewImage(params) {
  const url = params?.url || String(params);
  const children = (
    <img src={url} style={{ display: "block", maxWidth: "100%" }} />
  );
  return show({
    children,
    modalProps: params?.props,
    callback: params?.callback,
  });
}

这样可以更灵活的使用文件预览或者其他信息展示。