ConfirmModal二次确认弹窗

1,016 阅读1分钟

之前使用二次确认弹窗组件都是直接传入一个visible来控制组件的显示隐藏,最近使用了vben后,发现vben框架中有许多值得借鉴的地方,特意记录一下,下面直接上代码。

实现效果: image.png

  1. index.vue
//包装后的计算props
const innerPropsRef = ref<Partial<BasicType>>();
// 获取封装后的getProps
const getProps = computed(() => {
  return { ...props, ...unref(innerPropsRef) } as BasicType;
});
//设置属性
const setProps = (props?: Partial<BasicType>) => {
  innerPropsRef.value = { ...unref(innerPropsRef), ...props };
};

const emit = defineEmits(['register']);

onMounted(() => {
    //将子组件的方法通过emit注册的方式派发给useConfirmModal
    emit('register', { setProps, setModalProps });
    // 是否添加到body上
    const instance = getCurrentInstance() as any;
    if (document && getProps.value.appendToBody && instance && instance.ctx && instance.ctx.$el) {
      document.body.appendChild(instance.ctx.$el);
    }
});

/**
  * @description: 禁止页面滚动
*/
watch(
    () => getProps.value.visible,
    (val) => {
      document.body.style.overflow = val ? 'hidden' : 'auto';
    },
);
  1. confirmModal.vue
export function useConfirmModal(props?: Partial<BasicType>): [(any) => void, any] {
  let modalRef = ref();
  function register(instance: any) {
    isProdMode() &&
      onUnmounted(() => {
        modalRef.value = null;
      });

    if (unref(modalRef) && isProdMode() && instance === unref(modalRef)) return;

    props && instance.setProps(props);
    modalRef = instance;
  }
  function getModalInstance() {
    const confirmModal = unref(modalRef);
    if (!confirmModal) {
      console.error(
        '缺少confirmModal实例',
      );
    }
    return confirmModal;
  }

  //方法
  const methods = {
    setModalProps: (props): void => {
      getModalInstance()?.setModalProps(props);
    },
    openModal: (visible = true): void => {
      // console.log('getModalInstance()?', getModalInstance());
      getModalInstance()?.setModalProps({
        visible: visible,
      });
    },
    closeModal: () => {
      getModalInstance()?.setModalProps({ visible: false });
    },
    ....
  };
  return [register, methods];
}
  1. 导出 index.ts
import ConfirmModal from './src/index.vue';
import { useConfirmModal } from './src/hooks/confirmModal';
export { ConfirmModal, useConfirmModal };
  1. 使用
  <template>
     <!-- 二次确认弹窗 -->
     <ConfirmModal @register="registerConfirmModal" />
  </template>

<script lang="ts" setup name="xxxx">
 import { ConfirmModal, useConfirmModal } from '/@/custom-components/ConfirmModal';

 // 二次确认弹窗
 const [registerConfirmModal, { setModalProps, openModal: openConfirmModal, closeModal }] =
    useConfirmModal({
      title: '确认删除吗',
    });
    
 // 打开弹窗
 openConfirmModal();
 
 // 关闭弹窗
 closeModal();
</script>