前两天公司需要实现一个功能(用于大屏幕投屏):
自定义表头及内容 ,并且固定左边几列实现: 从左往右滚屏 滚动到后面没有列后 开始第二页的滚屏,以此类推 拉取到最后 没有数据又从第一页开始滚
实现思路:
- 监听滚动事件,
- 页面一加载去后台调用数据,成功后触发事件
- 判断是否滚动到最后 如果滚到最后 将scrollLeft 设置为0,没有就scrollLeft++;
div左边卷去的长度=div的总宽 - div屏幕可视区域的宽(div 即 设置overflow 的div )
上面的列子即为 scrollLeft=scroollWidth-clientWidth;
前后端商量 给什么样的数据结构 宽度,固定多少列,都有后台控制 如下:
后台分表头和数据 这样给 TableTitle + TableData 这样的结构 ;
具体代码如下:
<template>
<article class="schedule">
<header>
<h1>{{tilte}}</h1>
</header>
<article>
<template>
<el-table
ref="productionSchedle"
:data="tableData"
height="calc(100vh - 116px)"
>
<template
v-for="(item,index) in tableTitle">
<el-table-column
:width="item.width"
:prop="item.prop"
:label="item.title"
:fixed="item.fixed==='left'"
:render-header="renderHeader">
<template slot-scope="scope">
<span>{{scope.row[item.prop]}}</span>
</template>
</el-table-column>
</template>
</el-table>
</template>
</article>
</article>
</template>
<script>
export default {
name: "productionSchedule",
data() {
return {
tilte:'生产计划进度表',
tableTitle:[],
tableData:[],
page:1,
pageSize:0,
refreshTime:3000,
timer_code:'',
count:0, //计数
}
},
created(){
},
mounted(){
window.addEventListener('scroll', this.handleScroll,true);
this.getData();
},
watch: {},
methods: {
handleScroll(){
//重点代码
if(this.$refs.productionSchedle!=undefined){
// console.log(this.$refs);
let scollwidth=this.$refs.productionSchedle.$el.childNodes[2].scrollWidth;
let scrollLeft=this.$refs.productionSchedle.$el.childNodes[2].scrollLeft;
let clientWidth=this.$refs.productionSchedle.$el.childNodes[2].clientWidth;
let num=scollwidth-clientWidth;
if(parseInt(scrollLeft) == num){
if(this.count==0){ //此处是为了防止scrollLeft 会出现约等于的值 如果不判断会进来很多次,就会调很多次接口,并且 page 可能+多次 就看不到 一页一页的效果
this.count++;
this.getData().then(()=>{
this.count=0; //成功后修改状态
console.log("成功");
}).catch((error)=>{
console.log("异常错误"+error);
});
};
}else{
//实现滚动的代码
this.$refs.productionSchedle.$refs.bodyWrapper.scrollLeft++;
};
}
},
getData(){
let _param={page:this.page,pagesize:this.pageSize};
return new Promise((resolve, reject) => {
this.$axios({
method: 'post',
url:'http://接口域名/reportapi/YisJyReportOperation/SelProducePlanSpeedReportData',
headers: { token: localStorage.getItem('yis_pc_token') },
data: _param
}).then(response => {
if (response.data.errcode=="1000") {
console.log(response.data);
this.tilte=unescape(response.data.retdata[0].MainTitle[0].Title);
this.pageSize=unescape(response.data.retdata[0].MainTitle[0].Size);
this.refreshTime=(unescape(response.data.retdata[0].MainTitle[0].RefreshTime)*1000);
if(JSON.stringify(response.data.retdata[0].TableTitle)=="[{}]"){
return false
}
let tableTitle=response.data.retdata[0].TableTitle;
tableTitle.forEach((item,index)=>{
item.prop=unescape(item.prop); //后台乱码传的 >>>解码
item.title=unescape(item.title);
item.fixed=unescape(item.fixed);
item.width=unescape(item.width);
});
this.tableTitle=tableTitle;
if(JSON.stringify(response.data.retdata[0].TableData)=="[{}]"){
console.log("无数据~");
this.page=1;
this.pageSize=0;
this.getData();
}else{
this.page++;
let tableData=response.data.retdata[0].TableData;
tableData.forEach((item,index)=>{
for(let i in item){
item[i]=unescape(item[i])
};
});
this.tableData=tableData;
console.log("触发滚动事件")
//需要把当前的触发事件放在成功后并且有数据返回,无数据时调用接口
setTimeout(()=>{
this.$refs.productionSchedle.$refs.bodyWrapper.scrollLeft=1; //触发滚动事件
},3000);
};
resolve(response);
}else {
window.removeEventListener('scroll', this.handleScroll); //移除监听事件
this.showToast("info",response.data.errmsg);
resolve(response.data.errmsg)
};
},(error) => {
//如果错误移除监听事件
window.removeEventListener('scroll', this.handleScroll);
this.showToast("error",error);
reject(error);
});
})
},
showToast(type, msg) {
if (type == "success") {
this.$notification({
message: msg,
type: "success"
});
} else if (type == "error") {
this.$notification({
message: msg,
type: "error"
});
} else if (type == "info") {
this.$notification({
message: msg,
type: "warning"
});
}
},
// render 事件
renderHeader(h,{column}) { // h即为cerateElement的简写,具体可看vue官方文档
return h(
'span',
{domProps: {
innerHTML: `${column.label}`
},},
[],);
},
},
destroyed(){
console.log("销毁");
window.removeEventListener('scroll', this.handleScroll);
},
}
</script>
<style scoped lang="less">
@yellow:#ff5402;
.schedule{
background-color: #000000;
height: 99.5vh;
padding-top: 0.1px;
header{
background-color:@yellow;
height: 80px;
margin-bottom: 15px;
border-radius: 40px;
text-indent: 30px;
h1{
text-align: left;
line-height: 80px;
/*font-size: 2.5rem;*/
font-size: 4rem;
margin-top: 15px;
}
}
article{
height: auto;
}
article::-webkit-scrollbar {
width: 8px; /*高宽分别对应横竖滚动条的尺寸*/
height: 10px;
}
article::-webkit-scrollbar-thumb {
border-radius: 5px;
background: #7d7b7c;
}
article::-webkit-scrollbar-track {
border-radius: 0;
background: #979596;
}
}
</style>
<style lang="less">
.schedule{
@import "~@/components/reportCommon/theme.less";
/* .el-table__body{
width: auto!important;
min-width: 100% !important;
}
.el-table__header{
width: auto!important;
min-width: 100% !important;
}*/
.el-table{
color: #ffffff;
&::before{
height: 0px;
}
th,tr {
background-color: rgb(101,99,100);
}
th.is-leaf {
border-bottom: 1px dashed #ff5402;
text-align: center;
}
.cell {
/* font-size: 1.5rem !important;*/
span{
font-size: 2.2rem !important;
}
//line-height: 28px;
}
}
.el-table__body-wrapper{
background-color: #656365;
}
/deep/ .el-table__body tr.hover-row > td{
background: none;
}
/deep/ .el-table--enable-row-hover .el-table__body tr:hover>td {
background: none;
}
.el-table__fixed::before{
height: 0px;
}
.el-table__fixed{
&:nth-last-of-type(1){
margin-top: 83px !important;
}
}
.el-table td, .el-table th.is-leaf {
border-bottom: 1px dashed #ff5402;
text-align: center;
/* font-size: 1.5rem;*/
}
.el-table thead {
color: #ff5402;
font-weight: 500;
}
.el-table__header {
span{
/* font-size: 1.5rem;*/
font-size:2.5rem;
}
}
.el-table__empty-block {
background-color: #656364 ;
}
.el-table--scrollable-y .el-table__body-wrapper::-webkit-scrollbar {/*滚动条整体样式*/
.el-table-scrollbar;
}
.el-table--scrollable-y .el-table__body-wrapper::-webkit-scrollbar-thumb {/*滚动条里面小方块*/
.el-table-scrollbar-thumb_gary;
}
.el-table--scrollable-y .el-table__body-wrapper::-webkit-scrollbar-track {/*滚动条里面轨道*/
.el-table-scrollbar-track_gary;
}
.el-table--scrollable-x .el-table__body-wrapper::-webkit-scrollbar {/*滚动条整体样式*/
.el-table-scrollbar;
}
.el-table--scrollable-x .el-table__body-wrapper::-webkit-scrollbar-thumb {/*滚动条里面小方块*/
.el-table-scrollbar-thumb_gary;
}
.el-table--scrollable-x .el-table__body-wrapper::-webkit-scrollbar-track {/*滚动条里面轨道*/
.el-table-scrollbar-track_gary;
}
}
</style>