前言
如果项目使用了elementUI,可以看一下。如果没有使用,可以看我的另一篇文章,用div写的滚动表格
项目看板滚动数据显示。
参考文章:Element动态生成表格以及表格内容无缝滚动
感谢这篇文章的思路,开阔了思路。
指令版
需求(功能)
- 数据按条滚动
- 支持自定义列内容
- 设置表格背景色和字体颜色
本来还想加个鼠标移入停止,移出重新滚动的功能,但是指令里没法监听。这个功能就没法实现
效果图
实现代码
let value = (el, binding) => {
//console.log("表格:", el);
//默认参数
let defaultOptions = {
//页面最多显示的行数
maxNumner: 4,
//滚动速度(毫秒)
speed: 1500,
//数据总条数,默认5
totalNumber: 5,
//是否滚动,默认滚动
isScroll: true,
//背景色
background: "#FFFFFF",
//字体颜色
color: "#909399",
};
//参数处理
let options = Object.assign(defaultOptions, binding.value);
//获取表格头部
let elHeader = el.getElementsByClassName("has-gutter")[0];
//设置表头背景色和字体颜色(可以多级)
for (let tr of elHeader.childNodes) {
for (let th of tr.childNodes) {
th.style.background = options.background;
th.style.color = options.color;
}
}
//elHeader.style.background = "blue";
//获取el-table表格的容器,如果class变了,可能会出问题
let elwrapper = el.getElementsByClassName("el-table__body-wrapper")[0];
//console.log("容器:", elwrapper);
//设置容器高度,50固定不要随意修改
elwrapper.style.height = options.maxNumner * 50 + "px";
//获取表格主体
let elBody = elwrapper.getElementsByClassName("el-table__body")[0];
//获取每一行
let elRow = elBody.getElementsByClassName("el-table__row");
//设置行高,默认50不要修改,试过自定义有些问题
for (let node of elRow) {
node.style.height = 50 + "px";
//设置表格的颜色
node.style.background = options.background;
//设置字体颜色
node.style.color = options.color;
}
//设置滚动样式
elBody.style.position = "absolute";
elBody.style.transition = "all 500ms linear";
//设置过度时间
elBody.style.transactionDuration = "500ms";
//初始化窗口位置
elBody.style.top = 0;
//定时器,标识
let mark = undefined;
//当前所在行
let active = 0;
if (options.isScroll) {
//当页面显示的行数小于总条数时滚动
if (options.maxNumner < options.totalNumber) {
mark = setInterval(() => {
if (active < options.totalNumber) {
active += 1;
elBody.style.top = parseInt(elBody.style.top) - 17 + "px";
} else {
active = 0;
elBody.style.top = 0;
}
}, options.speed);
}
} else {
window.clearInterval(mark);
}
};
export default {
name: "roll",
mounted: value,
updated: value,
};
使用
<template>
<div >
<el-table :data="tableData" style="width: 100%" border v-roll="options">
<el-table-column prop="date" label="Date" width="180" />
<el-table-column prop="name" label="Name" width="180" />
<el-table-column prop="address" label="Address" />
</el-table>
</div>
</template>
<script>
export default {
data() {
return {
tableData: [
{
date: "2016-05-03",
name: "Tom",
address: "No. 189, Grove St, Los Angeles",
},
{
date: "2016-05-02",
name: "Tom",
address: "No. 189, Grove St, Los Angeles",
},
{
date: "2016-05-04",
name: "Tom",
address: "No. 189, Grove St, Los Angeles",
},
{
date: "2016-05-01",
name: "Tom",
address: "No. 189, Grove St, Los Angeles",
},
{
date: "2016-05-01",
name: "Tom",
address: "No. 189, Grove St, Los Angeles",
},
{
date: "2016-05-01",
name: "Tom",
address: "No. 189, Grove St, Los Angeles",
},
],
//滚动配置项
options:{
totalNumber:6,
isScroll:true,
background:'#2B9ACA',
color:'#000000'
}
};
},
mounted() {},
methods: {
},
};
</script>
<style scoped lang="scss">
</style>
组件版
实现代码
<template>
<div
@mouseover="stopSrcoll"
@mouseout="startSrcoll"
@mousewheel="handleWheel">
<el-table :data="tableData" :border="showBorder" style="width: 100%" ref="everTable"
:header-cell-style="headerStyle" :cell-style="cellStyle">
<slot></slot>
</el-table>
</div>
</template>
<script>
export default {
name: 'DtSrcoll',
props: {
// 表格主体
tableData: {
type: Array,
default: () => []
},
// 是否显示边框
showBorder: {
type: Boolean,
default: false
},
lineHeight: {
// 页面需要显示的行数
type: Number,
default: 4
},
rowTime: {
// 每一行滚动切换等待的时间(毫秒)
type: Number,
default: 1500
},
duration: {
// 过渡时间
type: Number,
default: 500
},
tableHeight: {
// 行高
type: Number,
default: 50
},
isClear: {
// 数据滚动到最后一行是否停止滚动
type: Boolean,
default: false
},
isAgain: {
// 数据滚动到最后一行是否重新开始滚动
type: Boolean,
default: true
},
isScroll: {
// 是否允许内容滚动
type: Boolean,
default: true
},
headerStyle: {
// 表头样式
type: [Object,Function]
},
cellStyle: {
// 单元格样式
type: [Object,Function]
}
},
data() {
return {
// 标识
active: 0,
// 定时器
timer: '',
// 容器
elwrapper: undefined
};
},
mounted() {
this.startSrcoll();
},
methods: {
// 开始滚动
startSrcoll() {
let _this = this;
// console.log(this.$refs.everTable.$el);
let everTable = this.$refs.everTable.$el;
this.$nextTick(() => {
let elwrapper = everTable.getElementsByClassName(
'el-table__body-wrapper'
)[0];
this.elwrapper = elwrapper;
let elBody = everTable.getElementsByClassName('el-table__body')[0];
_this.elBody = elBody;
elBody.style.position = 'absolute';
elBody.style.transition = 'all 500ms linear';
setTimeout(() => {
let elRow = everTable.getElementsByClassName('el-table__row');
for (let node of elRow) {
node.style.height = _this.tableHeight + 'px';
}
elwrapper.style.height = _this.lineHeight * _this.tableHeight + 'px';
},1000);
elBody.style.top = 0;
elBody.style.transactionDuration = this.duration + 'ms';
if (_this.isScroll) {
_this.timer = setInterval(function () {
if (
_this.active <
parseInt(_this.tableData.length) - parseInt(_this.lineHeight)
) {
_this.active += 1;
elBody.style.top =
parseInt(elBody.style.top) - parseInt(_this.tableHeight) + 'px';
} else {
if (this.isClear) {
clearInterval(this.timer);
}
if (_this.isAgain) {
_this.active = 0;
elBody.style.top = 0;
} else {
clearInterval(_this.timer);
}
}
}, _this.rowTime);
}
});
},
// 停止滚动
stopSrcoll() {
clearInterval(this.timer);
},
// 处理滑轮事件
handleWheel(e) {
// console.log('容器:',this.elwrapper);
// 负加正减
if(e.wheelDeltaY < 0) {
this.elwrapper.scrollTop += 10;
}else{
this.elwrapper.scrollTop -= 10;
}
// console.log(this.elwrapper.scrollTop);
}
},
destroyed() {
clearInterval(this.timer);
}
};
</script>
<style lang="scss" scoped>
</style>
使用
<template>
<div style="height: 100%; width: 98%; margin: 0 1%">
<dt-srcoll showBorder :tableData="dutyRateData">
<el-table-column label="序号" type="index" width="60" align="center"></el-table-column>
<el-table-column prop="date" label="Date" min-width="180" align="center" />
<el-table-column prop="name" label="Name" min-width="180" align="center" />
<el-table-column label="Address" align="center" >
<el-table-column
prop="country"
label="国家"
min-width="180"
align="center"
/>
<el-table-column
prop="provience"
label="省"
min-width="180"
align="center"
/>
</el-table-column>
</dt-srcoll>
</div>
</template>
<script>
import dtSrcoll from "@/views/yc/test/roll-table/dt-srcoll";
export default {
components: { dtSrcoll },
data() {
return {
dutyRateData: [
{
date: "2016-05-03",
name: "Tom",
country: "中国",
provience: "山东",
},
{
date: "2016-05-02",
name: "Tom",
country: "中国",
provience: "山东",
},
{
date: "2016-05-04",
name: "Tom",
country: "中国",
provience: "山东",
},
{
date: "2016-05-01",
name: "Tom",
country: "中国",
provience: "山东",
},
{
date: "2016-05-04",
name: "Tom",
country: "中国",
provience: "山东",
},
{
date: "2016-05-01",
name: "Tom",
country: "中国",
provience: "山东",
},
],
};
},
mounted() {},
methods: {},
};
</script>
<style scoped lang="scss">
</style>
关于表格背景色和字体颜色的问题:
最初是加了两个props属性,background
:背景色,color
:字体颜色。但是有两个致命的点
- 表头可以正常渲染,但是关于表格的行,不会渲染。原因是行是动态生成的,第一次渲染时没有获取到dom,后来加了个延时函数,可以正常渲染出来但是会出现一个闪烁。实现如下:
// 设置表头背景色和字体颜色(可以多级)
let elHeader = document.getElementsByClassName('has-gutter')[0];
for (let tr of elHeader.childNodes) {
for (let th of tr.childNodes) {
th.style.background = _this.background;
th.style.color = _this.color;
}
}
//设置表格主体
setTimeout(() => {
let elRow = document.getElementsByClassName('el-table__row');
for (let node of elRow) {
node.style.height = _this.tableHeight + 'px';
// 设置表格的颜色
node.style.background = _this.background;
// 设置字体颜色
node.style.color = _this.color;
}
}, 100);
- 最致命的是上面那种形式,实现的样式比较单一。如果你有比较特别的样式需求,比如我需要的样式就比较特别。最后只能使用element-table自身提供的实现形式
关于表格和单元哥样式的设置,以及表格的其他用法,可以看我的这篇文章
element——table表格常用点
注:如果要改变表头和表格的颜色,可能还需要改一下表格的整体颜色,如下:
/deep/ .el-table{
background: rgb(9, 24, 79);
}