vue
复制代码
<template>
<div class="lamp-container">
<div class="lamp-header">
<el-row :gutter="10">
<el-col v-for="col in column" :key="col.prop" :span="col.span || 6">
<slot :name="col.headSlot" :col="col">{{ col.label }}</slot>
</el-col>
</el-row>
</div>
<div
class="lamp-wrapper"
:style="{ height: height + 'px' }"
ref="wrapper"
@mouseover="stopCount"
@mouseout="count"
>
<div class="lamp-list" ref="list">
<div class="lamp-slide" v-for="item in data">
<el-row :gutter="10">
<el-col v-for="col in column" :key="col.prop" :span="col.span || 6">
<slot :name="col.slot" :row="item">{{ item[col.prop] }}</slot>
</el-col>
</el-row>
</div>
</div>
<div class="lamp-list" v-if="showClone">
<div class="lamp-slide" v-for="item in data">
<el-row :gutter="10">
<el-col v-for="col in column" :key="col.prop" :span="col.span || 6">
<slot :name="col.slot" :row="item">{{ item[col.prop] }}</slot>
</el-col>
</el-row>
</div>
</div>
</div>
</div>
</template>
<script>
/**
* @file 跑马灯组件 my-lamp
* @author 孔
* @date 2023-12-25
* @param column {() => ({
* label: '名称', 列标题
* prop: 'name', data 中的属性
* span: 6, 列宽度
* slot: 'name', 数据插槽
* headSlot:'name', 表头插槽}[])} 列配置
* @param data {Array} 数据
* @param height {Number} 高度
* @param speed {Number} 速度
* @slot headSlot {String} 表头插槽
* @slot slot {String} 数据插槽
*
* column item配置 {
* }
*/
export default {
name: "MyLamp",
props: {
column: Array,
data: Array,
height: {
type: [Number, String],
default: 200,
},
speed: {
type: Number,
default: 1,
},
},
data() {
return {
showClone: false,
timer: null,
};
},
watch: {
data: {
handler() {
this.init();
},
deep: true,
immediate: true,
},
},
beforeDestroy() {
if (this.timer) clearInterval(this.timer);
},
methods: {
init() {
this.$nextTick(() => {
if (this.$refs.list.offsetHeight > this.height) {
this.showClone = true;
this.count();
} else {
this.showClone = false;
this.stopCount();
}
});
},
stopCount() {
if (this.timer) clearInterval(this.timer);
},
count() {
if (!this.showClone) return;
if (this.timer) clearInterval(this.timer);
this.timer = setInterval(() => {
this.Marquee();
}, 50);
},
Marquee() {
if (this.$refs.wrapper.scrollTop >= this.$refs.list.offsetHeight) {
this.$refs.wrapper.scrollTop = 0;
} else {
this.$refs.wrapper.scrollTop += Number(this.speed);
}
},
},
};
</script>
<style scoped>
.lamp-header {
height: 40px;
line-height: 40px;
text-align: center;
font-size: 14px;
}
.lamp-wrapper {
overflow: hidden;
position: relative;
}
.lamp-wrapper .lamp-slide {
height: 40px;
line-height: 40px;
text-align: center;
}
.lamp-wrapper .lamp-slide:nth-child(even) {
background: #08247e;
}
</style>