vue 开发间隔式自动滚动组件
项目需求千奇百怪,只能尽其所能实现一二。
因开发vue前端,故此次使用vue开发一个间隔式自动滚动组件,代码如下
<template>
<div id="autoScrll"></div>
</template>
<script>
export default {
name: 'autoScroll',
props: {
ele: HTMLDivElement,// 滚动容器dom元素 必填
step: { // 步进值 正数 非必填 默认 10
type: Number,
default: 10
},
interval: { // 距下一次滚动时间间隔 单位ms 非必填 默认1000ms
type: Number,
default: 1000
},
mode: { // 滚动模式 1:按步进值(step)跳跃式滚动, 2:按照步进值(step)动画方式滚动
type: Number,
default: 1
},
speed: { // 模式2 下可设置滚动速度
type: Number,
default: 25
}
},
data() {
return {
scrollStep: 0, // 由于props中的值不能直接修改,在data中再声明一个变量,用于动态的修改步进值
stopScrollTopFlag: false,
stTimeout: undefined,
stInterval: undefined,
slTimeout: undefined,
slInterval: undefined
}
},
methods: {
autoScrollTop() {
if (this.ele) {
if (!this.scrollStep) {
if (!this.step || isNaN(this.step)) this.scrollStep = 10;
else this.scrollStep = this.step
}
if (!this.interval || isNaN(this.interval)) this.interval = 1000;
if (this.scrollStep < 10 || !this.mode) mode = 1;
const hh = this.ele.offsetHeight;
const hh2 = this.ele.scrollHeight;
if (hh2 > hh) {
let i = 0;
let ss = 0;
let scroll = this.ele.scrollTop;
if (scroll <= 0 || scroll >= (hh2 - hh)) {
scroll = 0;
} else {
i = (scroll / this.scrollStep ) + (scroll % this.scrollStep == 0 ? 0 : 1);
if ((this.scrollStep * i) >= (hh2 - hh)) {
if (scroll % this.scrollStep == 0) {
i = 0;
scroll = 0;
} else {
ss = (this.scrollStep * i) - scroll;
scroll = this.scrollStep * i;
}
}
}
if (this.mode == 1) {
// 开始滚动 每次步进滚动一个step高度
this.stInterval = setInterval(() => {
this.ele.scrollTop = scroll;
if ((hh + scroll) >= hh2) {
scroll = 0;
} else {
scroll += this.scrollStep ;
}
}, this.interval);
} else if (this.mode == 2) {
this.scrollToTop(hh, hh2, i, scroll - ss);
}
}
}
},
scrollToTop(hh, hh2, i, scroll) {
let interval2 = setInterval(() => {
if (!this.stopScrollTopFlag) {
this.ele.scrollTop = scroll;
if ((hh + scroll) >= hh2) {
i = 0;
scroll = 0;
clearInterval(interval2);
this.stTimeout = setTimeout(() => {
if (!this.stopScrollTopFlag) {
this.scrollToTop(hh, hh2, i, scroll);
this.stopScrollTop();
} else {
this.stopScrollTop();
}
}, this.interval);
} else if (scroll >= (this.scrollStep * i)) {
i++;
clearInterval(interval2);
this.stTimeout = setTimeout(() => {
if (!this.stopScrollTopFlag) {
this.scrollToTop(hh, hh2, i, scroll);
this.stopScrollTop();
} else {
this.stopScrollTop();
}
}, this.interval);
} else {
scroll += 2;
}
} else {
clearInterval(interval2);
}
}, this.speed);
},
stopScrollTop () {
if (this.stTimeout) {
clearTimeout(this.stTimeout);
this.stTimeout = undefined;
}
if (this.stInterval) {
clearInterval(this.stInterval);
this.stInterval = undefined;
}
}
}
}
</script>
这里在之前写好的table表格组件中引用,实现表格的自动滚动效果,代码如下:
<template>
<div>
<div class="table-head">
<table class="layui-table" style="">
<colgroup>
<col v-for="(colItem, idx) in cols" :key="'col-' + idx" :style="{width: getColWidth(colItem)}"/>
</colgroup>
<thead>
<tr>
<th
v-for="(colItem, idx2) in cols"
:key="'th-' + idx2"
:style="{textAlign: getAlign(colItem)}"
>{{ colItem.title }}</th>
</tr>
</thead>
</table>
</div>
<div ref="dataTableBox" class="table-body" :style="{height: getHeight()}">
<!-- 重点:使用引入的autoScroll组件 -->
<!-- $refs.dataTableBox 为监听的滚动的容器 dataTableBox 为容器 ref属性对应的值 -->
<auto-scroll ref="autoScroll" :ele="$refs.dataTableBox" :step="0" :interval="1500" :mode="2" />
<table ref="dataTable" class="layui-table" style="background: #0001271a;">
<colgroup>
<col v-for="(colItem, idx3) in cols" :key="'col2-' + idx3" :style="{width: getColWidth(colItem)}"/>
</colgroup>
<!-- <tbody ref="dataTableBody" v-if="data && data.length > 0" @mouseover="stopScroll" @mouseleave="startToScroll"> -->
<!-- 重点:鼠标移入或移动时停止滚动,鼠标移除时继续开始滚动 -->
<tbody ref="dataTableBody" v-if="data && data.length > 0" @mousemove="stopScroll2" @mouseover="stopScroll2" @mouseleave="startToScroll2">
<tr v-for="(dtItem, idx5) in data" :key="'dt-' + idx5" :class="[idx5%2 == 1 ? 'color1' : '']">
<td v-for="(colItem, idx6) in cols" :key="'col3-' + idx6" :style="{textAlign: getAlign(colItem)}">
<div v-if="colItem.type && colItem.type == 'num'">{{ idx5 + 1 }}</div>
<div v-else>{{ dtItem[colItem.field] }}</div>
</td>
</tr>
</tbody>
<tbody v-else>
<tr class="color1">
<td :colspan="cols.length" style="text-align: center;">暂无数据</td>
</tr>
</tbody>
</table>
</div>
<div :class="[isShow==5?'load_more':'load_more1']" v-if="isload">
<div @click="loadMore()">加载更多<img src="../assets/images/loadMore.png" alt=""></div>
</div>
</div>
</template>
<script>
import autoScroll from './autoScroll.vue'
export default {
name: 'tablePy',
components: {autoScroll},
props: {
"cols": {
type: Array,
default: [
{type: "num", title: '序号'},
{field: "field1", title: '字段1'},
{type: "field2", title: '字段2'},
]
},
"data": {
type: Array,
default: []
},
"isload": {
type: Boolean,
default: false
},
"height": {
type: String|Number,
default: 190
}
},
data() {
return {
datas: [],
// autoScroll: autoScroll,
scrollInterval: undefined
}
},
watch: {
data() {
// 重点:监听到表格数据变化时,等待数据表格渲染完成,再开始渲染自动滚动
// this.$refs.autoScroll.scrollStep 动态的修改间歇式滚动的步进值
this.$nextTick(() => {
// this.ele = this.$refs.dataTableBox;
this.$refs.autoScroll.scrollStep = this.$refs.dataTableBody.firstElementChild.offsetHeight;
this.startToScroll2();
});
}
},
methods: {
loadMore() {
this.$emit('loadMore');
return false;
},
getTitle(colItem) {
const title = colItem.title;
if (title) {
return title;
} else {
if (colItem.type && colItem.type == 'num') {
return '序号';
} else {
return colItem.field;
}
}
},
getColWidth(colItem) {
const type = colItem.type;
const width = colItem.width;
if (width) {
if ((width + '').slice(-1) == '%' || (width + '').slice(-2) == 'px') {
return width;
} else {
return width + 'px';
}
} else {
if (type && 'num' == type) {
return 80 + 'px';
} else {
return 'auto';
}
}
},
getAlign(colItem) {
const align = colItem.align;
if (align && ('center' == align || 'left' == align || 'right' == align)) {
return align;
} else {
return left;
}
},
getHeight() {
if ((this.height + '').slice(-1) == '%' || (this.height + '').slice(-2) == 'px') {
return this.height;
} else {
if (Number(this.height) < 90) {
return '90px';
} else {
return this.height + 'px';
}
}
},
stopScroll2() {
// 修改子组件变量值,调用子组件停止滚动方法
this.$refs.autoScroll.stopScrollTopFlag = true;
this.$refs.autoScroll.stopScrollTop();
},
startToScroll2() {
// 调用子组件开始滚动方法
this.$refs.autoScroll.stopScrollTopFlag = false;
this.$refs.autoScroll.autoScrollTop();
}
},
mounted() {
// 通过$once来监听定时器,在beforeDestroy钩子可以被清除。
this.$once('hook:beforeDestroy', () => {
this.stopScroll2();
});
}
};
</script>
<style lang="less" scoped>
.table-body {
width: 100%;
overflow-y: auto;
}
.table-body::-webkit-scrollbar {
width: 0;
}
table.layui-table {
margin: 0;
width: 100%;
color: #ffffff;
background: rgba(14, 43, 117, 0.3);
thead {
tr {
background: rgba(14, 43, 117, 0.3);
}
}
// tr {
// width: 100%;
// display: flex;
// overflow: hidden;
// background: rgba(14, 43, 117, 0.5);
// }
th, td {
border: none;
font-size: 16px;
padding: 9px 3px;
}
.color1 {
background: #07164e88;
}
tbody tr:hover {
background: rgba(14, 43, 117, 0.6);
}
}
.load_more {
margin-top: 0.4rem;
width: 110%;
height: 0.45rem;
border: 0.01rem solid #32c5ff;
font-size: 0.16rem;
line-height: 0.45rem;
text-align: center;
cursor: pointer;
margin-bottom: 0.5rem;
color: #32c5ff;
img {
width: 0.2rem;
height: 0.12rem;
}
}
.load_more1 {
margin-top: 0.4rem;
width: 100%;
height: 0.45rem;
border: 0.01rem solid #32c5ff;
font-size: 0.16rem;
line-height: 0.45rem;
text-align: center;
cursor: pointer;
margin-bottom: 0.5rem;
color: #32c5ff;
img {
width: 0.2rem;
height: 0.12rem;
}
}
</style>
代码比较多,第二段中相应的引用和使用方法已做 注明。
目前只写了纵向滚动的,等有时间再补充横向滚动的相关效果

浙公网安备 33010602011771号