213 lines
4.9 KiB
Vue
213 lines
4.9 KiB
Vue
<script lang="ts">
|
|
export default {
|
|
name: "LayLayer",
|
|
};
|
|
</script>
|
|
|
|
<script lang="ts" setup>
|
|
import { onMounted, onUpdated, ref, useSlots, watch } from "vue";
|
|
import useMove from "../../hooks/useMove";
|
|
import { guid } from "../../tools/guidUtil";
|
|
|
|
const slot = useSlots();
|
|
|
|
onMounted(() => {
|
|
moveHandle();
|
|
});
|
|
|
|
onUpdated(() => {
|
|
moveHandle();
|
|
});
|
|
|
|
export interface LayLayerProps {
|
|
id?: string;
|
|
zIndex?: number;
|
|
title?: string;
|
|
offset?: string[];
|
|
width?: string;
|
|
height?: string;
|
|
visible?: boolean | string;
|
|
maxmin?: boolean | string;
|
|
btn?: Record<string, unknown>[];
|
|
move?: boolean | string;
|
|
type?: number;
|
|
content?: string;
|
|
shade?: boolean | string;
|
|
shadeClose?: boolean | string;
|
|
closeBtn?: boolean | string;
|
|
btnAlign?: string;
|
|
anim?: number | boolean;
|
|
isOutAnim?: boolean;
|
|
}
|
|
|
|
const props = withDefaults(defineProps<LayLayerProps>(), {
|
|
id: "layer-" + guid(),
|
|
zIndex: 99999999,
|
|
title: "标题",
|
|
offset: () => ["50%", "50%"],
|
|
width: "390px",
|
|
height: "330px",
|
|
visible: true,
|
|
maxmin: false,
|
|
move: false,
|
|
type: 1,
|
|
btn: () => [],
|
|
shade: false,
|
|
shadeClose: true,
|
|
closeBtn: true,
|
|
btnAlign: "l",
|
|
anim: 0,
|
|
content: "",
|
|
isOutAnim: true
|
|
});
|
|
|
|
const top = ref(props.offset[0]);
|
|
const left = ref(props.offset[1]);
|
|
const width = ref(props.width);
|
|
const height = ref(props.height);
|
|
const max = ref(false);
|
|
const contentHeight = ref(
|
|
props.btn.length > 0
|
|
? "calc(" + height.value + " - 100px)"
|
|
: "calc(" + height.value + " - 50px)"
|
|
);
|
|
|
|
watch(max, function () {
|
|
if (max.value) {
|
|
contentHeight.value =
|
|
props.btn.length > 0 ? "calc(100% - 100px)" : "calc(100% - 50px)";
|
|
} else {
|
|
contentHeight.value =
|
|
props.btn.length > 0
|
|
? "calc(" + height.value + " - 100px)"
|
|
: "calc(" + height.value + " - 50px)";
|
|
}
|
|
});
|
|
|
|
const emit = defineEmits(["close", "update:visible"]);
|
|
|
|
const moveHandle = function () {
|
|
if (props.move) {
|
|
const el = document.getElementById(props.id);
|
|
if (el != null) {
|
|
useMove(el);
|
|
}
|
|
}
|
|
};
|
|
|
|
const shadeHandle = function () {
|
|
if (props.shadeClose) {
|
|
emit("close");
|
|
emit("update:visible", false);
|
|
}
|
|
};
|
|
|
|
const closeHandle = function () {
|
|
emit("close");
|
|
emit("update:visible", false);
|
|
};
|
|
|
|
const minHandle = function () {
|
|
emit("close");
|
|
emit("update:visible", false);
|
|
};
|
|
|
|
const maxHandle = function () {
|
|
if (max.value) {
|
|
width.value = props.width;
|
|
height.value = props.height;
|
|
top.value = props.offset[0];
|
|
left.value = props.offset[1];
|
|
} else {
|
|
width.value = "100%";
|
|
height.value = "100%";
|
|
top.value = "0px";
|
|
left.value = "0px";
|
|
}
|
|
max.value = !max.value;
|
|
};
|
|
</script>
|
|
|
|
<template>
|
|
<!-- 遮盖 -->
|
|
<div
|
|
v-if="visible && shade"
|
|
class="layui-layer-shade"
|
|
style="background-color: rgb(0, 0, 0); opacity: 0.1"
|
|
:style="{ zIndex: zIndex }"
|
|
@click="shadeHandle"
|
|
></div>
|
|
<!-- 元素 -->
|
|
<transition :leave-to-class="isOutAnim ? 'layer-anim-close':''">
|
|
<div
|
|
v-if="visible"
|
|
:id="id"
|
|
:class="[
|
|
anim!== false ? 'layer-anim layer-anim-0' + anim : '',
|
|
type === 1 ? 'layui-layer-dialog' : '',
|
|
type === 2 ? 'layui-layer-iframe' : '',
|
|
]"
|
|
class="layui-layer layui-layer-border"
|
|
:style="{
|
|
top: top,
|
|
left: left,
|
|
width: width,
|
|
height: height,
|
|
zIndex: zIndex,
|
|
}"
|
|
>
|
|
<div class="layui-layer-title" style="cursor: move">
|
|
{{ title }}
|
|
</div>
|
|
<div class="layui-layer-content" :style="{ height: contentHeight }">
|
|
<div v-if="type === 1" style="height: 100%">
|
|
<slot v-if="slot.default"></slot>
|
|
<template v-else>
|
|
{{ content }}
|
|
</template>
|
|
</div>
|
|
<iframe
|
|
v-if="type === 2"
|
|
scrolling="auto"
|
|
allowtransparency="true"
|
|
frameborder="0"
|
|
:src="content"
|
|
style="width: 100%; height: 100%"
|
|
></iframe>
|
|
</div>
|
|
<span class="layui-layer-setwin"
|
|
><a
|
|
v-if="maxmin"
|
|
class="layui-layer-min"
|
|
href="javascript:;"
|
|
@click="minHandle"
|
|
><cite></cite></a
|
|
><a
|
|
v-if="maxmin"
|
|
class="layui-layer-ico layui-layer-max"
|
|
:class="[max ? 'layui-layer-maxmin' : '']"
|
|
href="javascript:;"
|
|
@click="maxHandle"
|
|
></a>
|
|
<a
|
|
v-if="closeBtn"
|
|
class="layui-layer-ico layui-layer-close layui-layer-close1"
|
|
href="javascript:;"
|
|
@click="closeHandle"
|
|
></a
|
|
></span>
|
|
<div
|
|
v-if="btn && btn.length > 0"
|
|
class="layui-layer-btn"
|
|
:class="['layui-layer-btn-' + btnAlign]"
|
|
>
|
|
<template v-for="(b, index) in btn" :key="index">
|
|
<a :class="['layui-layer-btn' + index]" @click="b.callback">{{
|
|
b.text
|
|
}}</a>
|
|
</template>
|
|
</div>
|
|
<span class="layui-layer-resize"></span>
|
|
</div>
|
|
</transition>
|
|
</template> |