import { defineComponent, h, inject, onMounted, ref, watch, computed } from "vue"; import { useDialog } from "./helper"; import { Browser } from "../../types"; import { isArray, isBoolean } from "../../utils"; import { renderNode } from "../../utils/vnode"; export default defineComponent({ name: "cl-dialog", props: { // 是否可见 modelValue: { type: Boolean, default: false }, // 标题 title: { type: String, default: "对话框" }, // 高度 height: String, // 宽度 width: { type: String, default: "50%" }, // 是否缓存 keepAlive: Boolean, // 是否拖动 drag: { type: Boolean, default: true }, // el-dialog 参数 props: { type: Object, default: () => { return {}; } }, // 控制按钮 controls: { type: Array, default: () => ["fullscreen", "close"] }, // 是否隐藏控制按钮 hiddenControls: { type: Boolean, default: false }, // 隐藏头部元素 hiddenHeader: { type: Boolean, default: false } }, emits: ["update:modelValue", "fullscreen-change", "open", "opened", "close", "closed"], setup(props, { emit }) { const browser = inject("browser") as Browser; // 是否全屏 const fullscreen = ref(props.props.fullscreen); // 是否可见 const visible = ref(props.modelValue); // 缓存数 const cacheKey = ref(0); // 是否全屏 const isFullscreen = computed(() => { return browser.isMini ? true : fullscreen.value; }); // 对话框事件 const { setDialog } = useDialog({ isFullscreen, props }); // 监听绑定值 watch( () => props.modelValue, (val: boolean) => { visible.value = val; } ); // 监听 fullscreen 变化 watch( () => props.props.fullscreen, (val: boolean) => { fullscreen.value = val; } ); watch(fullscreen, (val: boolean) => { emit("fullscreen-change", val); }); watch(isFullscreen, setDialog); function close() { emit("update:modelValue", false); } // 关闭前 function beforeClose() { if (props.props["before-close"]) { props.props["before-close"](close); } else { close(); } } function onOpen() { // 初始值 fullscreen.value = props.props.fullscreen; // 是否缓存 if (!props.keepAlive) { cacheKey.value += 1; } setDialog(); emit("open"); } function onOpened() { emit("opened"); } function onClose() { emit("close"); close(); } function onClosed() { emit("closed"); } // 切换全屏 function changeFullscreen(val?: boolean) { fullscreen.value = isBoolean(val) ? Boolean(val) : !fullscreen.value; } // 双击全屏 function dblClickFullscreen() { if (isArray(props.controls) && props.controls.includes("fullscreen")) { changeFullscreen(); } } onMounted(function () { setDialog(); }); return { visible, fullscreen, isFullscreen, cacheKey, close, onOpen, onOpened, onClose, onClosed, changeFullscreen, beforeClose, dblClickFullscreen }; }, render(ctx: any) { const browser = inject("browser") as Browser; // 渲染头部 function renderHeader() { return ctx.hiddenHeader ? null : (
{/* 标题 */} {ctx.title} {/* 控制按钮 */}
{ctx.controls.map((vnode: any) => { // 全屏按钮 if (vnode === "fullscreen") { // 隐藏全屏 if (browser.screen === "xs") { return null; } // 是否显示全屏按钮 if (ctx.isFullscreen) { return ( ); } else { return ( ); } } // 关闭按钮 else if (vnode === "close") { return ( ); } else { return renderNode(vnode, { slots: ctx.$slots }); } })}
); } // el-dialog 对话框 const ElDialog = ( ); // 自定义样式 const customClass = `cl-dialog cl-dialog--${ctx.$.uid} ${ctx.props.customClass || ""}`; // 对话框高度 const height = ctx.height ? (ctx.isFullscreen ? `calc(100vh - 46px)` : ctx.height) : null; return (
{h( ElDialog, { ...ctx.props, customClass, fullscreen: ctx.isFullscreen }, { title() { return renderHeader(); }, default() { return (
{ctx.$slots.default && ctx.$slots.default()}
); }, footer() { return ( ); } } )}
); } });