之前使用二次确认弹窗组件都是直接传入一个visible来控制组件的显示隐藏,最近使用了vben后,发现vben框架中有许多值得借鉴的地方,特意记录一下,下面直接上代码。
实现效果:
- 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';
},
);
- 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];
}
- 导出 index.ts
import ConfirmModal from './src/index.vue';
import { useConfirmModal } from './src/hooks/confirmModal';
export { ConfirmModal, useConfirmModal };
- 使用
<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>