1.组件的使用
<div class="bottomcenterdetail">
<el-row class="goodshort">
<el-col :span="6">序号</el-col><el-col :span="12">货品名称</el-col><el-col :span="6" style="text-align:right">滞留时长(天)</el-col>
</el-row>
<div style="height:93%; overflow: hidden;">
<autoScroll :data="timeoutList" :speed="0.5" :waitTime="500" :singleHeight="100" v-if="timeoutList.length>0">
<el-row v-for="(item,index) in timeoutList" :key="index" class="goodshortli">
<el-col class="goodshortlist" :span="6">{{index+1}}</el-col>
<el-col class="goodshortlist" :span="12" :title="item.goodsName">{{item.goodsName}}</el-col>
<el-col class="goodshortlist" style="text-align:right" :span="6">{{item.stayTime}}</el-col>
</el-row>
</autoScroll>
<div v-else class="zanwushuju">暂无数据</div>
</div>
</div>
2.数据格式
import autoScroll from "@/components/houseCard/autoScroll.vue"
export default {
name:'first',
components: { autoScroll },
data(){
return{
timeoutList:[{goodsName:'小马',stockNumber:'1'}],
}
}
}
3.组件样式
.bottomcenterdetail{
width:100%;
height:95%;
.goodshort{
height:30px;
line-height:30px;
color:rgb(109, 131, 140);
font-size:12px;
background:rgb(1, 40, 55)
}
.goodshortlist{
height: 30px;
font-size: 12px;
padding:0px 6px;
font-family: MicrosoftYaHei;
line-height: 30px;
overflow: hidden;//(文字长度超出限定宽度,则隐藏超出的内容)
white-space: nowrap;//(设置文字在一行显示,不能换行)
text-overflow: ellipsis;//(规定当文本溢出时,显示省略符号来代表被修剪的文本)
}
.goodshortli{
color:#3DE1ED
}
.goodshortli:nth-child(odd){
background-image: url(../image/goodlistbg.png);
background-repeat: no-repeat; /* 取消重复平铺 */
}
.goodshortli:nth-child(-n+6){
color:#FE0000;
}
.goodshortli:nth-child(n+7):nth-child(-n+11){
color:#FDD35D;
}
}
4.autoScroll.vue,封装好的组件
<template>
<div class="scroll-outer" ref="outer" @mouseover="onMouseover" @mouseleave="onMouseleave">
<div class="scroll-inner-box" ref="scrollBox">
<div class="scroll-item-box" ref="scrollItemBox">
<slot></slot>
</div>
<div v-if="showSecond" class="scroll-item-box">
<slot></slot>
</div>
</div>
</div>
</template>
<script>
export default {
name: "autoScroll",
props: {
list: {
type: Array,
default: () => [
// { name: "张三1" },
// { name: "张三2" },
],
},
speed: {
type: Number,
default:'',
},
//滚动作单步运动时的单纯运动距离
singleHeight: {
type: Number,
default: '',
},
//单步运动的时间间隔
waitTime: {
type: Number,
default: '',
},
},
data() {
return {
rafId: null,
y: 0,
showSecond: false,
controleHeight: 0,
};
},
watch: {
list: {
handler(newVal) {
var that = this;
this.$nextTick(() => {
if (newVal && newVal.length > 0) {
let scrollBox = that.$refs.scrollBox;
let outer = that.$refs.outer;
if (this.myReq) {
cancelAnimationFrame(this.myReq);
}
// 开启动画
if (this.canRun())
this.reqAnimationFrame();
// 手动滚动到底部时滚动条重置到最上边,同时滚动盒子重置为top:0
outer.addEventListener("scroll", function () {
if (
outer.scrollTop + outer.clientHeight + 4 >= outer.scrollHeight
) {
outer.scrollTop = 0;
that.y = 0;
scrollBox.style.top = 0;
}
});
}
});
},
deep: true,
immediate: true,
},
},
mounted() {
this.$nextTick(()=>{
window.addEventListener("resize", this.listenResizeFn);
this.onMouseover()
this.onMouseleave()
})
},
methods: {
listenResizeFn() {
cancelAnimationFrame(this.myReq);
if (this.canRun()) this.reqAnimationFrame();
},
// 鼠标移入
onMouseover() {
clearTimeout(this.timer);
cancelAnimationFrame(this.myReq);
},
// 鼠标离开
onMouseleave() {
if (this.canRun())
this.reqAnimationFrame();
},
canRun() {
let scrollItemBox = this.$refs.scrollItemBox;
let scrollBox = this.$refs.scrollBox;
let outer = this.$refs.outer;
// 开启动画条件:滚动盒子(scrollBox)高度高于外层容器(outer)高度
if (outer.offsetHeight >= scrollItemBox.offsetHeight) {
this.showSecond = false;
outer.scrollTop = 0;
this.y = 0;
scrollBox.style.top = 0;
return false;
} else {
this.showSecond = true;
return true;
}
},
//获取dom元素的高度:content+padding+margin+border
getComputedHeight(dom) {
let computedStyle = getComputedStyle(dom);
let computedHeight =
dom.offsetHeight +
parseFloat(computedStyle.marginTop) +
parseFloat(computedStyle.marginBottom);
return computedHeight;
},
reqAnimationFrame() {
//外层容器
let outer = this.$refs.outer;
//滚动盒子
let scrollBox = this.$refs.scrollBox;
//滚动盒子下边的第一个scroll-item-box,
let scrollItemBox = this.$refs.scrollItemBox;
//滚动速度
this.speed = this.speed > 1 ? 1 : this.speed < 0 ? 0.1 : this.speed;
//取第一个scrollItemBox高度
let definedHeight = this.getComputedHeight(scrollItemBox);
//持续滚动
this.y = this.y + this.speed;
scrollBox.style.top = -this.y + "px";
//====添加滚动间隔控制====开始
if (this.singleHeight >= 20 && this.waitTime > 500) {
if (this.controleHeight >= this.singleHeight) {
cancelAnimationFrame(this.myReq);
this.controleHeight = 0;
this.timer = setTimeout(() => {
if (this.canRun) this.reqAnimationFrame();
}, this.waitTime);
return;
} else {
// 一次移动高度未达到指定距离继续执行动画
this.controleHeight += this.speed;
}
}
//====添加滚动间隔控制====结束
//当滚动到第一个scroll-item-box高度时scrollBox重置为top:0,视觉上是无缝滚动
if (this.y >= definedHeight) {
this.y = 0;
}
this.myReq = window.requestAnimationFrame(this.reqAnimationFrame);
},
},
destroyed() {
window.removeEventListener("resize", this.listenResizeFn);
cancelAnimationFrame(this.myReq);
if (this.timer) clearTimeout(this.timer);
},
};
</script>
<style lang="less" scoped>
.scroll-outer {
height: 100%;
overflow-x: hidden;
position: relative;
&::-webkit-scrollbar {
width: 0.3vw;
}
&:hover::-webkit-scrollbar-track {
-webkit-box-shadow: inset 0 0 0.1vw rgba(0, 0, 0, 0.3);
border-radius: 0.1vw;
background-color: #295099;
opacity: 1;
// display: none;
}
&:hover::-webkit-scrollbar-thumb {
opacity: 1;
border-radius: 0.1vw;
-webkit-box-shadow: inset 0 0 0.1vw rgba(0, 0, 0, 0.3);
background-color: #0ba9ea;
}
}
.scroll-inner-box {
height: auto;
position: absolute;
width: 100%;
top: 0;
left: 0;
}
</style>