update src/component/noticeBar/index.vue.
This commit is contained in:
		
							parent
							
								
									797adf2c57
								
							
						
					
					
						commit
						a02749d959
					
				@ -0,0 +1,194 @@
 | 
			
		||||
<template>
 | 
			
		||||
	<div class="notice-bar" :style="{ background, height: `${height}px` }" v-show="!isMode">
 | 
			
		||||
		<div class="notice-bar-warp" :style="{ color, fontSize: `${size}px` }">
 | 
			
		||||
			<lay-icon v-if="leftIcon" class="notice-bar-warp-left-icon" :type="leftIcon"></lay-icon>
 | 
			
		||||
			<div class="notice-bar-warp-text-box" ref="noticeBarWarpRef">
 | 
			
		||||
				<div class="notice-bar-warp-text" ref="noticeBarTextRef" v-if="!scrollable">{{ text }}</div>
 | 
			
		||||
				<div class="notice-bar-warp-slot" v-else><slot /></div>               
 | 
			
		||||
			</div> 
 | 
			
		||||
             <lay-icon :type="rightIcon" v-if="rightIcon" class="notice-bar-warp-right-icon" @click="onRightIconClick"></lay-icon>
 | 
			
		||||
		</div>
 | 
			
		||||
	</div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import { toRefs, reactive, defineComponent, ref, onMounted, nextTick } from 'vue';
 | 
			
		||||
export default defineComponent({
 | 
			
		||||
	name: 'noticeBar',
 | 
			
		||||
	props: {
 | 
			
		||||
		// 通知栏模式,可选值为 closeable link
 | 
			
		||||
		mode: {
 | 
			
		||||
			type: String,
 | 
			
		||||
			default: () => '',
 | 
			
		||||
		},
 | 
			
		||||
		// 通知文本内容
 | 
			
		||||
		text: {
 | 
			
		||||
			type: String,
 | 
			
		||||
			default: () => '',
 | 
			
		||||
		},
 | 
			
		||||
		// 通知文本颜色
 | 
			
		||||
		color: {
 | 
			
		||||
			type: String,
 | 
			
		||||
			default: () => 'var(--color-warning)',
 | 
			
		||||
		},
 | 
			
		||||
		// 通知背景色
 | 
			
		||||
		background: {
 | 
			
		||||
			type: String,
 | 
			
		||||
			default: () => 'var(--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: () => '',
 | 
			
		||||
		},
 | 
			
		||||
		// 自定义右侧图标
 | 
			
		||||
		rightIcon: {
 | 
			
		||||
			type: String,
 | 
			
		||||
			default: () => '',
 | 
			
		||||
		},
 | 
			
		||||
	},
 | 
			
		||||
	setup(props, { emit }) {
 | 
			
		||||
		const noticeBarWarpRef = ref();
 | 
			
		||||
		const noticeBarTextRef = ref();
 | 
			
		||||
		const state = reactive({
 | 
			
		||||
			order: 1,
 | 
			
		||||
			oneTime: 0,
 | 
			
		||||
			twoTime: 0,
 | 
			
		||||
			warpOWidth: 0,
 | 
			
		||||
			textOWidth: 0,
 | 
			
		||||
			isMode: false,
 | 
			
		||||
		});
 | 
			
		||||
		// 初始化 animation 各项参数
 | 
			
		||||
		const initAnimation = () => {
 | 
			
		||||
			nextTick(() => {
 | 
			
		||||
				state.warpOWidth = noticeBarWarpRef.value.offsetWidth;
 | 
			
		||||
				state.textOWidth = noticeBarTextRef.value.offsetWidth;
 | 
			
		||||
				document.styleSheets[0].insertRule(`@keyframes oneAnimation {0% {left: 0px;} 100% {left: -${state.textOWidth}px;}}`);
 | 
			
		||||
				document.styleSheets[0].insertRule(`@keyframes twoAnimation {0% {left: ${state.warpOWidth}px;} 100% {left: -${state.textOWidth}px;}}`);
 | 
			
		||||
				computeAnimationTime();
 | 
			
		||||
				setTimeout(() => {
 | 
			
		||||
					changeAnimation();
 | 
			
		||||
				}, props.delay * 1000);
 | 
			
		||||
			});
 | 
			
		||||
		};
 | 
			
		||||
		// 计算 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 图标点击
 | 
			
		||||
		const onRightIconClick = () => {
 | 
			
		||||
			if (!props.mode) return false;
 | 
			
		||||
			if (props.mode === 'closeable') {
 | 
			
		||||
				state.isMode = true;
 | 
			
		||||
				emit('close');
 | 
			
		||||
			} else if (props.mode === 'link') {
 | 
			
		||||
				emit('link');
 | 
			
		||||
			}
 | 
			
		||||
		};
 | 
			
		||||
		// 页面加载时
 | 
			
		||||
		onMounted(() => {
 | 
			
		||||
			if (props.scrollable) return false;
 | 
			
		||||
			initAnimation();
 | 
			
		||||
			listenerAnimationend();
 | 
			
		||||
		});
 | 
			
		||||
		return {
 | 
			
		||||
			noticeBarWarpRef,
 | 
			
		||||
			noticeBarTextRef,
 | 
			
		||||
			onRightIconClick,
 | 
			
		||||
			...toRefs(state),
 | 
			
		||||
		};
 | 
			
		||||
	},
 | 
			
		||||
});
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style>
 | 
			
		||||
.notice-bar {
 | 
			
		||||
  padding: 0 15px;
 | 
			
		||||
  width: 100%;
 | 
			
		||||
  border-radius: 4px;
 | 
			
		||||
}
 | 
			
		||||
.notice-bar .notice-bar-warp {
 | 
			
		||||
  display: flex;
 | 
			
		||||
  align-items: center;
 | 
			
		||||
  width: 100%;
 | 
			
		||||
  height: inherit;
 | 
			
		||||
}
 | 
			
		||||
.notice-bar .notice-bar-warp .notice-bar-warp-text-box {
 | 
			
		||||
  flex: 1;
 | 
			
		||||
  height: inherit;
 | 
			
		||||
  display: flex;
 | 
			
		||||
  align-items: center;
 | 
			
		||||
  overflow: hidden;
 | 
			
		||||
  position: relative;
 | 
			
		||||
}
 | 
			
		||||
.notice-bar .notice-bar-warp .notice-bar-warp-text-box .notice-bar-warp-text {
 | 
			
		||||
  white-space: nowrap;
 | 
			
		||||
  position: absolute;
 | 
			
		||||
  left: 0;
 | 
			
		||||
}
 | 
			
		||||
.notice-bar .notice-bar-warp .notice-bar-warp-text-box .notice-bar-warp-slot {
 | 
			
		||||
  width: 100%;
 | 
			
		||||
  white-space: nowrap;
 | 
			
		||||
}
 | 
			
		||||
.notice-bar .notice-bar-warp .notice-bar-warp-text-box .notice-bar-warp-slot ::v-deep(.el-carousel__item) {
 | 
			
		||||
  display: flex;
 | 
			
		||||
  align-items: center;
 | 
			
		||||
}
 | 
			
		||||
.notice-bar .notice-bar-warp .notice-bar-warp-left-icon {
 | 
			
		||||
  width: 24px;
 | 
			
		||||
  font-size: inherit !important;
 | 
			
		||||
}
 | 
			
		||||
.notice-bar .notice-bar-warp .notice-bar-warp-right-icon {
 | 
			
		||||
  width: 24px;
 | 
			
		||||
  text-align: right;
 | 
			
		||||
  font-size: inherit !important;
 | 
			
		||||
}
 | 
			
		||||
.notice-bar .notice-bar-warp .notice-bar-warp-right-icon:hover {
 | 
			
		||||
  cursor: pointer;
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user