✨(component): [dropdown]menuItem 添加插槽,新增 subMenu
This commit is contained in:
@@ -17,43 +17,46 @@ export default {
|
||||
};
|
||||
</script>
|
||||
<script lang="ts" setup>
|
||||
import { nextTick, onMounted, ref } from 'vue';
|
||||
import CloseBtnVue from './CloseBtn.vue';
|
||||
import { nextTick, onMounted, ref } from "vue";
|
||||
import CloseBtnVue from "./CloseBtn.vue";
|
||||
|
||||
export interface LayNotifyProps {
|
||||
title: any;
|
||||
content: any;
|
||||
isHtmlFragment?: boolean;
|
||||
icon?: string | number | undefined,
|
||||
iconClass: string[]
|
||||
icon?: string | number | undefined;
|
||||
iconClass: string[];
|
||||
}
|
||||
const props = withDefaults(defineProps<LayNotifyProps>(), {
|
||||
isHtmlFragment: false,
|
||||
|
||||
});
|
||||
|
||||
const emit = defineEmits(['close'])
|
||||
const emit = defineEmits(["close"]);
|
||||
const close = () => {
|
||||
emit('close')
|
||||
}
|
||||
function addClass(obj: { className: any; }, cls: string) {
|
||||
emit("close");
|
||||
};
|
||||
function addClass(obj: { className: any }, cls: string) {
|
||||
//获取 class 内容.
|
||||
let obj_class = obj.className,
|
||||
//判断获取到的 class 是否为空, 如果不为空在前面加个'空格'.
|
||||
blank = (obj_class != '') ? ' ' : '';
|
||||
let added = obj_class + blank + cls;//组合原来的 class 和需要添加的 class.
|
||||
obj.className = added;//替换原来的 class.
|
||||
blank = obj_class != "" ? " " : "";
|
||||
let added = obj_class + blank + cls; //组合原来的 class 和需要添加的 class.
|
||||
obj.className = added; //替换原来的 class.
|
||||
}
|
||||
|
||||
const notifyRef = ref<HTMLElement | null>(null)
|
||||
const notifyRef = ref<HTMLElement | null>(null);
|
||||
onMounted(() => {
|
||||
nextTick(() => {
|
||||
if (notifyRef.value) {
|
||||
setTimeout(() => {//此处延迟加载class,以免影响弹出效果
|
||||
setTimeout(() => {
|
||||
//此处延迟加载class,以免影响弹出效果
|
||||
// @ts-ignore
|
||||
addClass(notifyRef.value.parentElement?.parentElement, 'layui-layer-notify')
|
||||
addClass(
|
||||
notifyRef.value.parentElement?.parentElement,
|
||||
"layui-layer-notify"
|
||||
);
|
||||
}, 300);
|
||||
}
|
||||
})
|
||||
})
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -59,20 +59,20 @@ export interface LayModalProps {
|
||||
move?: boolean | string;
|
||||
resize?: boolean | string;
|
||||
type?:
|
||||
| 0
|
||||
| 1
|
||||
| 2
|
||||
| 3
|
||||
| 4
|
||||
| 5
|
||||
| 6
|
||||
| "dialog"
|
||||
| "page"
|
||||
| "iframe"
|
||||
| "loading"
|
||||
| "drawer"
|
||||
| "photos"
|
||||
| "notifiy";
|
||||
| 0
|
||||
| 1
|
||||
| 2
|
||||
| 3
|
||||
| 4
|
||||
| 5
|
||||
| 6
|
||||
| "dialog"
|
||||
| "page"
|
||||
| "iframe"
|
||||
| "loading"
|
||||
| "drawer"
|
||||
| "photos"
|
||||
| "notifiy";
|
||||
content?: string | Function | object | VNodeTypes;
|
||||
isHtmlFragment?: boolean;
|
||||
shade?: boolean | string;
|
||||
@@ -119,12 +119,12 @@ const props = withDefaults(defineProps<LayModalProps>(), {
|
||||
resize: false,
|
||||
isHtmlFragment: false,
|
||||
isOutAnim: true,
|
||||
destroy: () => { },
|
||||
success: () => { },
|
||||
end: () => { },
|
||||
full: () => { },
|
||||
min: () => { },
|
||||
restore: () => { },
|
||||
destroy: () => {},
|
||||
success: () => {},
|
||||
end: () => {},
|
||||
full: () => {},
|
||||
min: () => {},
|
||||
restore: () => {},
|
||||
yesText: "确定",
|
||||
isFunction: false,
|
||||
isMessage: false,
|
||||
@@ -187,7 +187,7 @@ const firstOpenDelayCalculation = function () {
|
||||
}
|
||||
offset.value = calculateOffset(props.offset, area.value, props.type);
|
||||
if (type == 6) {
|
||||
offset.value = calculateNotifOffset(props.offset, area.value, id.value)
|
||||
offset.value = calculateNotifOffset(props.offset, area.value, id.value);
|
||||
}
|
||||
w.value = area.value[0];
|
||||
h.value = area.value[1];
|
||||
@@ -441,8 +441,9 @@ const styles = computed<any>(() => {
|
||||
offset.value[1].indexOf("%") > -1
|
||||
) {
|
||||
// @ts-ignore
|
||||
style.transform = `translate(-${style.left.indexOf("%") > -1 ? style.left : 0
|
||||
},-${style.top.indexOf("%") > -1 ? style.top : 0})`;
|
||||
style.transform = `translate(-${
|
||||
style.left.indexOf("%") > -1 ? style.left : 0
|
||||
},-${style.top.indexOf("%") > -1 ? style.top : 0})`;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -469,14 +470,13 @@ const contentClasses = computed(() => {
|
||||
* @param null
|
||||
*/
|
||||
const closeHandle = () => {
|
||||
|
||||
emit("close");
|
||||
emit("update:modelValue", false);
|
||||
props.destroy();
|
||||
|
||||
//Notify 从队列中移除当前实例
|
||||
if(type===6){
|
||||
removeNotifiyFromQueen(props.id)
|
||||
if (type === 6) {
|
||||
removeNotifiyFromQueen(props.id);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -619,15 +619,33 @@ defineExpose({ reset, open, close });
|
||||
<template>
|
||||
<div>
|
||||
<!-- 遮盖层 -->
|
||||
<Shade :index="index" :visible="shadeVisible" :opacity="shadeOpacity" @shadeClick="shadeHandle"></Shade>
|
||||
<Shade
|
||||
:index="index"
|
||||
:visible="shadeVisible"
|
||||
:opacity="shadeOpacity"
|
||||
@shadeClick="shadeHandle"
|
||||
></Shade>
|
||||
<!-- 动画容器 -->
|
||||
<transition :enter-active-class="enterActiveClass" :leave-active-class="leaveActiveClass">
|
||||
<transition
|
||||
:enter-active-class="enterActiveClass"
|
||||
:leave-active-class="leaveActiveClass"
|
||||
>
|
||||
<!-- 弹出层 -->
|
||||
<div ref="layero" class="layui-layer layui-layer-border" :class="boxClasses" :style="styles" v-if="visible">
|
||||
<div
|
||||
ref="layero"
|
||||
class="layui-layer layui-layer-border"
|
||||
:class="boxClasses"
|
||||
:style="styles"
|
||||
v-if="visible"
|
||||
>
|
||||
<!-- 标题 -->
|
||||
<Title v-if="showTitle" :title="title"></Title>
|
||||
<!-- 内容 -->
|
||||
<div class="layui-layer-content" :style="{ height: contentHeight }" :class="contentClasses">
|
||||
<div
|
||||
class="layui-layer-content"
|
||||
:style="{ height: contentHeight }"
|
||||
:class="contentClasses"
|
||||
>
|
||||
<template v-if="type === 0 || type === 1 || type === 4">
|
||||
<i v-if="icon" :class="iconClass"></i>
|
||||
<slot v-if="slots.default"></slot>
|
||||
@@ -639,26 +657,55 @@ defineExpose({ reset, open, close });
|
||||
</template>
|
||||
</template>
|
||||
<Iframe v-if="type === 2" :src="props.content"></Iframe>
|
||||
<Photos v-if="type === 5" :imgList="props.imgList" :startIndex="props.startIndex" @resetCalculationPohtosArea="resetCalculationPohtosArea"></Photos>
|
||||
<Notifiy v-if="type === 6" @close="closeHandle" :title="props.title" :content="props.content" :isHtmlFragment="props.isHtmlFragment" :icon="props.icon" :iconClass="iconClass"></Notifiy>
|
||||
<Photos
|
||||
v-if="type === 5"
|
||||
:imgList="props.imgList"
|
||||
:startIndex="props.startIndex"
|
||||
@resetCalculationPohtosArea="resetCalculationPohtosArea"
|
||||
></Photos>
|
||||
<Notifiy
|
||||
v-if="type === 6"
|
||||
@close="closeHandle"
|
||||
:title="props.title"
|
||||
:content="props.content"
|
||||
:isHtmlFragment="props.isHtmlFragment"
|
||||
:icon="props.icon"
|
||||
:iconClass="iconClass"
|
||||
></Notifiy>
|
||||
</div>
|
||||
<!-- 工具栏 -->
|
||||
<span class="layui-layer-setwin" v-if="type != 3 && type != 5 && type != 6">
|
||||
<a v-if="maxmin && !max" class="layui-layer-min" :class="[min ? 'layui-layer-ico layui-layer-maxmin' : '']"
|
||||
href="javascript:;" @click="minHandle">
|
||||
<span
|
||||
class="layui-layer-setwin"
|
||||
v-if="type != 3 && type != 5 && type != 6"
|
||||
>
|
||||
<a
|
||||
v-if="maxmin && !max"
|
||||
class="layui-layer-min"
|
||||
:class="[min ? 'layui-layer-ico layui-layer-maxmin' : '']"
|
||||
href="javascript:;"
|
||||
@click="minHandle"
|
||||
>
|
||||
<cite v-if="!min"></cite>
|
||||
</a>
|
||||
<a v-if="maxmin && !min" class="layui-layer-ico layui-layer-max" :class="[max ? 'layui-layer-maxmin' : '']"
|
||||
href="javascript:;" @click="maxHandle"></a>
|
||||
<a
|
||||
v-if="maxmin && !min"
|
||||
class="layui-layer-ico layui-layer-max"
|
||||
:class="[max ? 'layui-layer-maxmin' : '']"
|
||||
href="javascript:;"
|
||||
@click="maxHandle"
|
||||
></a>
|
||||
<CloseBtn v-if="closeBtn" @closeHandle="closeHandle"></CloseBtn>
|
||||
</span>
|
||||
<!-- 操作栏 -->
|
||||
<div v-if="((btn && btn.length > 0) || type === 0) && !isMessage" class="layui-layer-btn"
|
||||
:class="[`layui-layer-btn-${btnAlign}`]">
|
||||
<div
|
||||
v-if="((btn && btn.length > 0) || type === 0) && !isMessage"
|
||||
class="layui-layer-btn"
|
||||
:class="[`layui-layer-btn-${btnAlign}`]"
|
||||
>
|
||||
<template v-if="btn && btn.length > 0">
|
||||
<template v-for="(b, index) in btn" :key="index">
|
||||
<a :class="[`layui-layer-btn${index}`]" @click="b.callback(id)">{{
|
||||
b.text
|
||||
b.text
|
||||
}}</a>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
@@ -140,14 +140,14 @@ const layer = {
|
||||
},
|
||||
//通知
|
||||
notifiy: (option: any = {}, callback?: Function) => {
|
||||
option.anim = 5
|
||||
option.shade = false
|
||||
option.type = 6
|
||||
option.anim = 5;
|
||||
option.shade = false;
|
||||
option.type = 6;
|
||||
let defaultOption = {
|
||||
offset: 'rt',
|
||||
time:2000,
|
||||
area:'auto'
|
||||
}
|
||||
offset: "rt",
|
||||
time: 2000,
|
||||
area: "auto",
|
||||
};
|
||||
return layer.create(option, defaultOption, callback);
|
||||
},
|
||||
// 创建弹出层
|
||||
@@ -186,7 +186,11 @@ const layer = {
|
||||
// 调用 open 函数
|
||||
modalInstance.component?.exposed?.open();
|
||||
// 延时 time 销毁
|
||||
if (defaultOption && defaultOption.time != undefined && defaultOption.time != 0) {
|
||||
if (
|
||||
defaultOption &&
|
||||
defaultOption.time != undefined &&
|
||||
defaultOption.time != 0
|
||||
) {
|
||||
timer = setTimeout(() => {
|
||||
modalInstance.component?.exposed?.close();
|
||||
if (callback) callback(modalContainer.id);
|
||||
@@ -200,7 +204,7 @@ const layer = {
|
||||
delInstance(modalContainer.id);
|
||||
//Notifiy特殊处理
|
||||
if (options.type === 6) {
|
||||
removeNotifiyFromQueen(options.id)
|
||||
removeNotifiyFromQueen(options.id);
|
||||
}
|
||||
}, defaultOption.time);
|
||||
}
|
||||
|
||||
@@ -286,7 +286,8 @@ export async function calculatePhotosArea(url: string, options: object) {
|
||||
// 计算Notify位置 队列 此处先暂时定义Notify的间距为15px
|
||||
export function calculateNotifOffset(offset: any, area: any, layerId: string) {
|
||||
let arr = ["lt", "lb", "rt", "rb"];
|
||||
let t = '0', l = '0';
|
||||
let t = "0",
|
||||
l = "0";
|
||||
// 间隙
|
||||
let transOffsetLeft = 15;
|
||||
let transOffsetTop = 15;
|
||||
@@ -294,23 +295,25 @@ export function calculateNotifOffset(offset: any, area: any, layerId: string) {
|
||||
window.NotifiyQueen = window.NotifiyQueen || [];
|
||||
// @ts-ignore
|
||||
let notifiyQueen = window.NotifiyQueen;
|
||||
if (typeof offset != 'string' || arr.indexOf(offset) === -1) {
|
||||
if (typeof offset != "string" || arr.indexOf(offset) === -1) {
|
||||
offset = "rt";
|
||||
}
|
||||
// 当前区域元素集合
|
||||
let nodeList = notifiyQueen.filter((e: { offset: any; }) => {
|
||||
let nodeList = notifiyQueen.filter((e: { offset: any }) => {
|
||||
if (e.offset === offset) {
|
||||
return e
|
||||
return e;
|
||||
}
|
||||
})
|
||||
});
|
||||
//前一个元素
|
||||
let prevNode = nodeList.length > 0 ? nodeList[nodeList.length - 1] : null;
|
||||
if (prevNode) {
|
||||
prevNode = document.getElementById(prevNode['id'])?.firstElementChild?.firstElementChild;
|
||||
prevNode = document.getElementById(prevNode["id"])?.firstElementChild
|
||||
?.firstElementChild;
|
||||
if (offset === "rt" || offset === "lt") {
|
||||
transOffsetTop += prevNode.offsetHeight + parseFloat(prevNode.style['top'])
|
||||
transOffsetTop +=
|
||||
prevNode.offsetHeight + parseFloat(prevNode.style["top"]);
|
||||
} else {
|
||||
let bottom = parseFloat(prevNode.style['top'].split(' - ')[1])
|
||||
let bottom = parseFloat(prevNode.style["top"].split(" - ")[1]);
|
||||
transOffsetTop += prevNode.offsetHeight + bottom;
|
||||
}
|
||||
} else {
|
||||
@@ -324,20 +327,20 @@ export function calculateNotifOffset(offset: any, area: any, layerId: string) {
|
||||
t = transOffsetTop + "px";
|
||||
l = "calc(100% - " + (parseFloat(area[0]) + transOffsetLeft) + "px)";
|
||||
} else if (offset === "rb") {
|
||||
t = "calc(100vh - " + transOffsetTop + "px)"
|
||||
t = "calc(100vh - " + transOffsetTop + "px)";
|
||||
l = "calc(100% - " + (parseFloat(area[0]) + transOffsetLeft) + "px)";
|
||||
} else if (offset === "lt") {
|
||||
t = transOffsetTop + "px";
|
||||
l = transOffsetLeft + "px";
|
||||
} else if (offset === "lb") {
|
||||
t = "calc(100vh - " + transOffsetTop + "px)"
|
||||
t = "calc(100vh - " + transOffsetTop + "px)";
|
||||
l = transOffsetLeft + "px";
|
||||
}
|
||||
|
||||
notifiyQueen.push({
|
||||
id: layerId,
|
||||
offset: offset
|
||||
})
|
||||
offset: offset,
|
||||
});
|
||||
// 返回位置
|
||||
return [t, l];
|
||||
}
|
||||
@@ -347,33 +350,40 @@ export function removeNotifiyFromQueen(layerId: string | undefined) {
|
||||
// 间隙
|
||||
let transOffsetTop = 15;
|
||||
// @ts-ignore 删除项的高度
|
||||
let offsetHeight = document.getElementById(layerId)?.firstElementChild?.firstElementChild?.offsetHeight;
|
||||
let offsetHeight =
|
||||
document.getElementById(layerId)?.firstElementChild?.firstElementChild
|
||||
?.offsetHeight;
|
||||
// @ts-ignore
|
||||
window.NotifiyQueen = window.NotifiyQueen || [];
|
||||
// @ts-ignore
|
||||
let notifiyQueen = window.NotifiyQueen;
|
||||
//console.log(notifiyQueen)
|
||||
let index = notifiyQueen.findIndex((e: { id: string; }) => e.id === layerId)
|
||||
let index = notifiyQueen.findIndex((e: { id: string }) => e.id === layerId);
|
||||
let offsetType = notifiyQueen[index].offset;
|
||||
let list = notifiyQueen.filter((e: { offset: any; }) => {
|
||||
let list = notifiyQueen.filter((e: { offset: any }) => {
|
||||
if (e.offset === offsetType) {
|
||||
return e;
|
||||
}
|
||||
})
|
||||
let findIndex = list.findIndex((e: { id: string; }) => e.id === layerId)
|
||||
});
|
||||
let findIndex = list.findIndex((e: { id: string }) => e.id === layerId);
|
||||
// //得到需要修改的定位的Notifiy集合
|
||||
let needCalculatelist = list.slice(findIndex + 1)
|
||||
needCalculatelist.forEach((e: { id: string; }) => {
|
||||
let dom = document.getElementById(e.id)?.firstElementChild?.firstElementChild
|
||||
if (offsetType === 'rt' || offsetType === 'lt') {
|
||||
let needCalculatelist = list.slice(findIndex + 1);
|
||||
needCalculatelist.forEach((e: { id: string }) => {
|
||||
let dom = document.getElementById(e.id)?.firstElementChild
|
||||
?.firstElementChild;
|
||||
if (offsetType === "rt" || offsetType === "lt") {
|
||||
// @ts-ignore
|
||||
dom.style['top'] = parseFloat(dom.style['top']) - transOffsetTop - offsetHeight + 'px'
|
||||
dom.style["top"] =
|
||||
parseFloat(dom.style["top"]) - transOffsetTop - offsetHeight + "px";
|
||||
} else {
|
||||
// @ts-ignore
|
||||
let bottom = parseFloat(dom.style['top'].split(' - ')[1]) - transOffsetTop - offsetHeight
|
||||
let bottom =
|
||||
parseFloat(dom.style["top"].split(" - ")[1]) -
|
||||
transOffsetTop -
|
||||
offsetHeight;
|
||||
// @ts-ignore
|
||||
dom.style['top'] = "calc(100vh - " + bottom + "px)"
|
||||
dom.style["top"] = "calc(100vh - " + bottom + "px)";
|
||||
}
|
||||
})
|
||||
notifiyQueen.splice(index, 1);//删除
|
||||
}
|
||||
});
|
||||
notifiyQueen.splice(index, 1); //删除
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user