<style lang="less" > table{ margin:0 auto; width:100%; overflow:visible; // thead{ // background: #eef4fe; // width:100vw; // // overflow-y: scroll; // // -webkit-overflow-scrolling: touch; // display:block; // position: -webkit-sticky; // position: sticky; // top:0px; // z-index: 999; // tr{ // td{ // height:40px; // text-align: center; // // border:1px solid #8a8a8a; // border-bottom:0; // box-sizing: border-box; // font-weight: bold; // font-size:14px; // position: sticky; // } // } // } tbody{ display:block; max-width:100vw; overflow: visible; ._tbody{ height:calc(100% - 40px); overflow: auto; -webkit-overflow-scrolling: touch; tr{ width:100%; box-sizing: border-box; display: flex; td{ display: flex; align-items: center; justify-content: center; min-height:40px; box-sizing: border-box; word-wrap: break-word; position: sticky; left:0; } } } ._thead,._tfoot{ -webkit-overflow-scrolling: touch; min-height:40px; overflow: auto; font-weight:bold; tr{ min-height:40px; box-sizing: border-box; display: flex; td{ display: flex; align-items: center; justify-content: center; min-height:40px; box-sizing: border-box; word-wrap: break-word; position: sticky; left:0; } } } } } .img{ width:100%; display: flex; justify-content: center; img{ width:100%; height:300px; } } </style> <template> <div class="_table"> <table v-if="LIST.length > 0"> <!-- <thead @scroll="scrollThead" ref="thead"> <tr> <td v-for="(item,index) in columns" :key="index" :style="{ 'text-align':item.align, 'width':item.width, 'min-width':item.width, 'max-width':item.width, 'border':tableStyle.theadTdBorder ? tableStyle.tbodyTrBorderBottom : '0px', 'background':tableStyle.theadBgColor, 'position': item.fixed ? 'sticky' : 'static', 'left':item.fixed ? item.fixedLeftWidth : 'none', }" > {{item.name}} </td> </tr> </thead> --> <tbody :style="{'height':tableStyle.tbodyHeight}"> <div class="_thead" ref="thead" @scroll="scrollThead" > <tr :style="{'width':'100%','min-width':tableStyle.width}"> <td v-for="(item,index) in columns" :key="index" :style="{ 'text-align':item.align, 'width':'100%', 'min-width':item.width, 'background':tableStyle.theadBgColor, 'position': item.fixed ? 'sticky' : 'static', 'left':item.fixed ? item.fixedLeftWidth : 'none', 'border-top':tableStyle.theadTdBorder ? tableStyle.tbodyTrBorderBottom : '0px', 'border-left':tableStyle.theadTdBorder ? tableStyle.tbodyTrBorderBottom : '0px', 'border-bottom':tableStyle.theadTdBorder ? tableStyle.tbodyTrBorderBottom : '0px', 'border-right':(index == columns.length - 1 && tableStyle.theadTdBorder) ? tableStyle.tbodyTrBorderBottom : '0px', }" > {{item.name}} </td> </tr> </div> <div class="_tbody" ref="tbody" @scroll="scrollTbody"> <tr v-for="(item,index) in LIST" :key="index" :style="{'width':'100%','min-width':tableStyle.width}"> <td v-for="(x,i) in columns" :key="i" :style="{ 'text-align':x.align, 'width':'100%', 'min-width':x.width, 'color':x.color, 'background':index % 2 == 0 ? tableStyle.complexTrBgColor : tableStyle.singleTrBgColor, 'text-overflow': x.ellipsis ? 'ellipsis' : 'none', 'overflow': x.ellipsis ? 'hidden' : 'none', 'white-space': x.ellipsis ? 'normal' : 'none', 'position': x.fixed ? 'sticky' : 'static', 'left':x.fixed ? x.fixedLeftWidth : 'none', 'border-left':tableStyle.tbodyTdBorder ? tableStyle.tbodyTrBorderBottom : '0px', 'border-right':(i == columns.length - 1 && tableStyle.tbodyTdBorder) ? tableStyle.tbodyTrBorderBottom : '0px', 'border-bottom':tableStyle.tbodyTrBorderBottom }" @click="clickTd(i,index)" v-html="item[x.field]" > </td> </tr> <slot></slot> </div> <div class="_tfoot" ref="tfoot" @scroll="scrollTFoot" v-if="showFooter & footerData.length > 0"> <tr v-for="(x,i) in footerData" :key="i" :style="{'width':'100%','min-width':tableStyle.width}"> <td v-for="(item,index) in columns" :key="index" :style="{ 'text-align':item.align, 'width':'100%', 'min-width':item.width, 'background':tableStyle.theadBgColor, 'position': item.fixed ? 'sticky' : 'static', 'left':item.fixed ? item.fixedLeftWidth : 'none', 'border-top':tableStyle.theadTdBorder ? tableStyle.tbodyTrBorderBottom : '0px', 'border-left':tableStyle.theadTdBorder ? tableStyle.tbodyTrBorderBottom : '0px', 'border-bottom':tableStyle.theadTdBorder ? tableStyle.tbodyTrBorderBottom : '0px', 'border-right':(index == columns.length - 1 && tableStyle.theadTdBorder) ? tableStyle.tbodyTrBorderBottom : '0px', }" v-html="x[item.field]" > </td> </tr> </div> </tbody> </table> <div class="img"> <img v-if="LIST.length <= 0" src="@/assets/noData.jpg" class="_img" alt=""> </div> </div> </template> <script> import Util from '@/libs/util.js' export default { name: 'Table', data () { return { x:0, y:0, isLoad:true, footerData:[], LIST:[] } }, props:{ columns: { type: Array, default: function(){ return []; } }, list: { type: Array, default: function(){ return [{}]; } }, tableStyle:{ type: Object, default: function(){ return { theadBgColor:'#eef4fe', complexTrBgColor:'#eef4fe', singleTrBgColor:'white', theadTdBorder:false, tbodyTdBorder:false, tbodyHeight:'100%', tbodyTrBorderBottom:'1px solid #5cadff' } } }, showFooter:{ type:Boolean, default:false } }, async mounted(){ window.d = this; this.isLoad = false; }, watch: { list: function(newVal,oldVal){ this.LIST = Util.deepClone(this.list); if(this.showFooter) this.footerData = this.LIST.splice(this.LIST.length - 1,1); }, }, methods:{ scrollTbody(e){ let thead = this.$refs['thead']; let tbody = this.$refs['tbody']; let tfoot = this.$refs['tfoot']; // if(tbody.scrollLeft > this.x){ // }else if(tbody.scrollLeft < this.x){ // } thead.scrollTo(tbody.scrollLeft,thead.scrollTop); if(tfoot){ tfoot.scrollTo(tbody.scrollLeft,tfoot.scrollTop); } if(tbody.scrollTop > this.y){ // console.log('向下') let offsetHeight = tbody.offsetHeight; let scrollHeight = tbody.scrollHeight; let scrollTop = tbody.scrollTop; if(scrollHeight - offsetHeight - scrollTop <= 0){ this.global.$emit('scrollTable'); } }else if(tbody.scrollTop < this.y){ // console.log('向上') } this.x = tbody.scrollLeft; this.y = tbody.scrollTop; }, scrollThead(){ let thead = this.$refs['thead']; let tbody = this.$refs['tbody']; let tfoot = this.$refs['tfoot']; if(tfoot){ tfoot.scrollTo(thead.scrollLeft,tfoot.scrollTop); } tbody.scrollTo(thead.scrollLeft,tbody.scrollTop); }, scrollTFoot(){ let thead = this.$refs['thead']; let tbody = this.$refs['tbody']; let tfoot = this.$refs['tfoot']; tbody.scrollTo(tfoot.scrollLeft,tbody.scrollTop); thead.scrollTo(tfoot.scrollLeft,thead.scrollTop); }, clickTd(i,index){ if(!this.columns[i].underline) return false; this.global.$emit('clickTd',{ trIndex:index, tdIndex:i, }); }, }, components:{ }, activated(){ if(this.isLoad){ let thead = this.$refs['thead']; let tbody = this.$refs['tbody']; if(this.LIST.length > 0){ tbody.scrollTo(this.x,this.y); thead.scrollTo(this.x,0); } } this.isLoad = true; }, beforeDestroy(){ } } </script>