😎优化noticeBar组件

This commit is contained in:
zuohuaijun 2024-08-04 00:41:34 +08:00
parent 6395bf0ff3
commit af309a7072
3 changed files with 62 additions and 125 deletions

View File

@ -2,7 +2,7 @@
"name": "admin.net.pro", "name": "admin.net.pro",
"type": "module", "type": "module",
"version": "2.4.33", "version": "2.4.33",
"lastBuildTime": "2024.08.03", "lastBuildTime": "2024.08.04",
"description": "Admin.NET 站在巨人肩膀上的 .NET 通用权限开发框架", "description": "Admin.NET 站在巨人肩膀上的 .NET 通用权限开发框架",
"author": "zuohuaijun", "author": "zuohuaijun",
"license": "MIT", "license": "MIT",
@ -68,7 +68,7 @@
"vue-signature-pad": "^3.0.2", "vue-signature-pad": "^3.0.2",
"vue3-tree-org": "^4.2.2", "vue3-tree-org": "^4.2.2",
"vuedraggable": "4.0.3", "vuedraggable": "4.0.3",
"vxe-pc-ui": "^4.0.84", "vxe-pc-ui": "^4.0.86",
"vxe-table": "^4.7.59", "vxe-table": "^4.7.59",
"vxe-table-plugin-element": "^4.0.4", "vxe-table-plugin-element": "^4.0.4",
"vxe-table-plugin-export-xlsx": "^4.0.5", "vxe-table-plugin-export-xlsx": "^4.0.5",

View File

@ -1,14 +1,13 @@
<template> <template>
<div class="notice-bar" :style="{ background, height: `${height}px` }" v-show="!state.isMode"> <div class="notice-bar" :style="{ background, height: `${height}px` }" v-show="!state.isMode">
<div class="notice-bar-warp" :style="{ color, fontSize: `${size}px` }"> <div class="notice-bar-warp" :style="{ color, fontSize: `${size}px` }" ref="noticeBarWarpRef">
<i v-if="leftIcon" class="notice-bar-warp-left-icon" :class="leftIcon"></i> <i v-if="leftIcon" class="notice-bar-warp-left-icon" :class="leftIcon"></i>
<div class="notice-bar-warp-text-box" ref="noticeBarWarpRef"> <div class="notice-bar-warp-text-box">
<div class="notice-bar-warp-text" ref="noticeBarTextRef" v-if="!scrollable"> <div class="notice-bar-warp-text" ref="noticeBarTextRef">
<div v-html="text" data-slate-editor /> <div v-html="text" data-slate-editor />
</div> </div>
<div class="notice-bar-warp-slot" v-else><slot /></div>
</div> </div>
<SvgIcon :name="rightIcon" v-if="rightIcon" class="notice-bar-warp-right-icon" @click="onRightIconClick" /> <!-- <SvgIcon :name="rightIcon" v-if="rightIcon" class="notice-bar-warp-right-icon" @click="onRightIconClick" /> -->
</div> </div>
</div> </div>
</template> </template>
@ -16,117 +15,65 @@
<script setup lang="ts" name="noticeBar"> <script setup lang="ts" name="noticeBar">
import { reactive, ref, onMounted, nextTick } from 'vue'; import { reactive, ref, onMounted, nextTick } from 'vue';
//
const props = defineProps({ const props = defineProps({
// closeable link mode: { type: String, default: '' }, // closeable link
mode: { text: { type: String, default: '欢迎使用 Admin.NET 通用权限开发框架 <a href="https://gitee.com/zuohuaijun/Admin.NET" target="_blank">https://gitee.com/zuohuaijun/Admin.NET</a>' }, //
type: String, color: { type: String, default: 'var(--el-color-warning)' }, //
default: () => '', background: { type: String, default: 'var(--el-color-warning-light-9)' }, //
}, size: { type: [Number, String], default: 14 }, // px
// height: { type: Number, default: 40 }, // px
text: { delay: { type: Number, default: 1 }, // (s)
type: String, speed: { type: Number, default: 200 }, // (px/s)
default: () => '欢迎使用 Admin.NET 通用权限开发框架 <a href="https://gitee.com/zuohuaijun/Admin.NET" target="_blank">https://gitee.com/zuohuaijun/Admin.NET</a>', scrollable: { type: Boolean, default: false }, //
}, leftIcon: { type: String, default: 'iconfont icon-tongzhi2' }, //
// rightIcon: { type: String, default: '' }, //
color: {
type: String,
default: () => 'var(--el-color-warning)',
},
//
background: {
type: String,
default: () => 'var(--el-color-warning-light-9)',
},
// px
size: {
type: [Number, String],
default: () => 14,
},
// px
height: {
type: Number,
default: () => 40,
},
// (s)
delay: {
type: Number,
default: () => 1,
},
// (px/s)
speed: {
type: Number,
default: () => 100,
},
//
scrollable: {
type: Boolean,
default: () => false,
},
//
leftIcon: {
type: String,
default: () => 'iconfont icon-tongzhi2',
},
//
rightIcon: {
type: String,
default: () => '',
},
}); });
// /
const emit = defineEmits(['close', 'link']); const emit = defineEmits(['close', 'link']);
const noticeBarWarpRef = ref<HTMLDivElement | null>(null);
// const noticeBarTextRef = ref<HTMLDivElement | null>(null);
const noticeBarWarpRef = ref();
const noticeBarTextRef = ref();
const state = reactive({ const state = reactive({
order: 1, isMode: false,
oneTime: 0,
twoTime: 0,
warpOWidth: 0, warpOWidth: 0,
textOWidth: 0, textOWidth: 0,
isMode: false, animationDuration: 0,
}); });
// animation //
onMounted(() => {
if (!props.scrollable) {
initAnimation();
}
});
//
const initAnimation = () => { const initAnimation = () => {
nextTick(() => { nextTick(() => {
state.warpOWidth = noticeBarWarpRef.value.offsetWidth; if (noticeBarWarpRef.value && noticeBarTextRef.value) {
state.textOWidth = noticeBarTextRef.value.offsetWidth; state.warpOWidth = noticeBarWarpRef.value.offsetWidth;
document.styleSheets[0].insertRule(`@keyframes oneAnimation {0% {left: 0px;} 100% {left: -${state.textOWidth}px;}}`); state.textOWidth = noticeBarTextRef.value.scrollWidth;
document.styleSheets[0].insertRule(`@keyframes twoAnimation {0% {left: ${state.warpOWidth}px;} 100% {left: -${state.textOWidth}px;}}`);
computeAnimationTime(); state.animationDuration = (state.textOWidth + state.warpOWidth) / props.speed;
setTimeout(() => {
changeAnimation(); // Clear existing animation styles
}, props.delay * 1000); noticeBarTextRef.value.style.animation = 'none';
noticeBarTextRef.value.offsetHeight; // Trigger reflow
noticeBarTextRef.value.style.animation = `marquee ${state.animationDuration}s linear infinite`;
// Define keyframes for marquee animation
const keyframes = `
@keyframes marquee {
0% { transform: translateX(${state.warpOWidth}px); }
100% { transform: translateX(-${state.textOWidth}px); }
}
`;
const styleSheet = document.createElement('style');
styleSheet.innerText = keyframes;
document.head.appendChild(styleSheet);
}
}); });
}; };
// animation
const computeAnimationTime = () => {
state.oneTime = state.textOWidth / props.speed;
state.twoTime = (state.textOWidth + state.warpOWidth) / props.speed;
};
// animation
const changeAnimation = () => {
if (state.order === 1) {
noticeBarTextRef.value.style.cssText = `animation: oneAnimation ${state.oneTime}s linear; opactity: 1;}`;
state.order = 2;
} else {
noticeBarTextRef.value.style.cssText = `animation: twoAnimation ${state.twoTime}s linear infinite; opacity: 1;`;
}
};
// animation
const listenerAnimationend = () => {
noticeBarTextRef.value.addEventListener(
'animationend',
() => {
changeAnimation();
},
false
);
};
// icon // icon
const onRightIconClick = () => { const onRightIconClick = () => {
if (!props.mode) return false; if (!props.mode) return false;
@ -137,12 +84,6 @@ const onRightIconClick = () => {
emit('link'); emit('link');
} }
}; };
//
onMounted(() => {
if (props.scrollable) return false;
initAnimation();
listenerAnimationend();
});
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
@ -162,19 +103,12 @@ onMounted(() => {
align-items: center; align-items: center;
overflow: hidden; overflow: hidden;
position: relative; position: relative;
.notice-bar-warp-text { margin-right: 35px;
white-space: nowrap; // .notice-bar-warp-text {
position: absolute; // white-space: nowrap;
left: 0; // position: absolute;
} // left: 0;
.notice-bar-warp-slot { // }
width: 100%;
white-space: nowrap;
:deep(.el-carousel__item) {
display: flex;
align-items: center;
}
}
} }
.notice-bar-warp-left-icon { .notice-bar-warp-left-icon {
width: 24px; width: 24px;

View File

@ -1,6 +1,9 @@
<template> <template>
<div class="sys-cache-container"> <div class="sys-cache-container">
<NoticeBar text="系统缓存数据管理,请慎重操作!" style="margin-bottom: 5px" /> <div>
<NoticeBar text="系统缓存数据管理,请慎重操作!" style="margin: 4px" />
</div>
<splitpanes class="default-theme"> <splitpanes class="default-theme">
<pane size="20"> <pane size="20">
<el-card shadow="hover" header="缓存列表" v-loading="state.loading" style="height: 100%" body-style="height:100%; overflow:auto"> <el-card shadow="hover" header="缓存列表" v-loading="state.loading" style="height: 100%" body-style="height:100%; overflow:auto">