通用表格:可折叠,可合并,多列折行显示,自定义固定头,自定义固定列,移动端,vue
一基本用法:js模板:<script>var genbody = `<table><colgroup><col width="20%"></col><col wid...
一 基本用法:
js模板:
<script>
var genbody = `
<table>
<colgroup>
<col width="20%"></col>
<col width="20%"></col>
<col width="20%"></col>
<col width="20%"></col>
<col width="20%"></col>
</colgroup>
<tbody v-for="(data,index) in tableData">
<tr>
<td>
{{index+1}}
</td>
<td>
{{data.RealName}}
</td>
<td>
{{data.Username}}
</td>
<td>
{{data.UnitName}}
</td>
<td>
{{data.StateStr}}
</td>
</tr>
</tbody>
</table>
`
var genhead = `
<table>
<colgroup>
<col width="20%"></col>
<col width="20%"></col>
<col width="20%"></col>
<col width="20%"></col>
<col width="20%"></col>
</colgroup>
<tbody>
<tr>
<td >
序号
</td>
<td>
姓名
</td>
<td>
用户名
</td>
<td>
部门名称
</td>
<td>
状态
</td>
</tr>
</tbody>
</table>
`;
</script>
css样式:
<style>
table{
width:385px;
}
tr {
height:40px;
}
td {
border: 1px solid #ebeef5;
word-break: break-all;
text-align: center;
padding: 0px;
vertical-align: middle;
}
</style>
html组件:
<body>
<my-head>
<gen-head ></gen-head>
</my-head>
<my-body>
<gen-body :table-data="UserArr" ></gen-body>
</my-body>
</body>
js函数:
无
效果:
五列数据,不可折叠,不可左右滑动,无固定行,无固定列,就是一个基本表格,想要什么样式在js模板或者写css
二:单行合并单元格
js模板:
<script>
var genbody = `
<table>
<colgroup>
<col width="20%"></col>
<col width="20%"></col>
<col width="20%"></col>
<col width="20%"></col>
<col width="20%"></col>
</colgroup>
<tbody v-for="(data,index) in tableData" :class="{on:index%2==0,off:index%2!=0}">
<tr>
<td colspan="2">
{{index+1}}
</td>
<td>
{{data.Username}}
</td>
<td>
{{data.UnitName}}
</td>
<td>
{{data.StateStr}}
</td>
</tr>
</tbody>
</table>
`
var genhead = `
<table>
<colgroup>
<col width="20%"></col>
<col width="20%"></col>
<col width="20%"></col>
<col width="20%"></col>
<col width="20%"></col>
</colgroup>
<tbody>
<tr>
<td colspan="2">
序号
</td>
<td>
用户名
</td>
<td>
部门名称
</td>
<td>
状态
</td>
</tr>
</tbody>
</table>
`;
</script>
css样式:
<style>
table{
width:385px;
}
tr {
height:40px;
}
td {
border: 1px solid #ebeef5;
word-break: break-all;
text-align: center;
padding: 0px;
vertical-align: middle;
}
.on {
background: #F5F7FA;
}
.off {
background: white;
}
</style>
其他不变.
效果:
:
三:多行,合并,隔行换色
js模板:
<script>
var genbody = `
<table>
<colgroup>
<col width="20%"></col>
<col width="20%"></col>
<col width="20%"></col>
<col width="20%"></col>
<col width="20%"></col>
</colgroup>
<tbody v-for="(data,index) in tableData">
<tr>
<td rowspan="2">
{{index+1}}
</td>
<td colspan="2">
{{data.Username}}
</td>
<td>
{{data.RealName}}
</td>
</tr>
<tr>
<td>
{{data.Username}}
</td>
<td>
{{data.UnitName}}
</td>
<td>
{{data.StateStr}}
</td>
</tr>
</tbody>
</table>
`
var genhead = `
<table>
<colgroup>
<col width="20%"></col>
<col width="20%"></col>
<col width="20%"></col>
<col width="20%"></col>
<col width="20%"></col>
</colgroup>
<tbody>
<tr>
<td rowspan="2">
序号
</td>
<td colspan="2">
用户名
</td>
<td >
姓名
</td>
</tr>
<tr>
<td>
用户名
</td>
<td>
部门名称
</td>
<td >
状态
</td>
</tr>
</tbody>
</table>
`;
</script>
其他不变:
效果:
四:三的基础上加上可展开折叠效果
js模板:
<script>
var genbody = `
<table>
<colgroup>
<col width="25%"></col>
<col width="25%"></col>
<col width="25%"></col>
<col width="25%"></col>
</colgroup>
<tbody v-for="(data,index) in tableData" :class="{on:index%2==0,off:index%2!=0}" @click="$emit('bodys',index)">
<tr>
<td rowspan="2">
{{index+1}}
</td>
<td colspan="2">
{{data.Username}}
</td>
<td>
{{data.RealName}}
</td>
</tr>
<tr v-show="store.Current == index">
<td>
{{data.Username}}
</td>
<td>
{{data.UnitName}}
</td>
<td>
{{data.StateStr}}
</td>
</tr>
</tbody>
</table>
`
var genhead = `
<table>
<colgroup>
<col width="25%"></col>
<col width="25%"></col>
<col width="25%"></col>
<col width="25%"></col>
</colgroup>
<tbody @click="$emit('heads')">
<tr>
<td rowspan="2">
序号
</td>
<td colspan="2">
用户名
</td>
<td >
姓名
</td>
</tr>
<tr v-show="head">
<td>
用户名
</td>
<td>
部门名称
</td>
<td >
状态
</td>
</tr>
</tbody>
</table>
`;
</script>
css样式:不变
html组件:
<my-head>
<gen-head @heads="heads" :head="head" ></gen-head>
</my-head>
<my-body>
<gen-body :table-data="UserArr" @bodys="bodys"></gen-body>
</my-body>
vue中的store(即vue中的data属性):
var store = {
Current: null,
body: false,
head: false,
...
}
vue中的methods(自定义点击事件的方法):
methods: {
bodys: function (index) {
if (store.Current == index) {
store.Current = null;
} else {
store.Current = index;
}
},
heads: function () {
if (store.head == true) {
store.head = false;
} else {
store.head = true;
}
},
...
}
效果:
五:四的基础上可左右滚定,
js模板:
<script>
var genbody = `
<table>
<colgroup>
<col width="12.5%"></col>
<col width="12.5%"></col>
<col width="12.5%"></col>
<col width="12.5%"></col>
<col width="12.5%"></col>
<col width="12.5%"></col>
<col width="12.5%"></col>
<col width="12.5%"></col>
</colgroup>
<tbody v-for="(data,index) in tableData" :class="{on:index%2==0,off:index%2!=0}" @click="$emit('bodys',index)">
<tr>
<td rowspan="2">
{{index+1}}
</td>
<td colspan="2">
{{data.Username}}
</td>
<td>
{{data.RealName}}
</td>
<td rowspan="2">
{{index+1}}
</td>
<td colspan="2">
{{data.Username}}
</td>
<td>
{{data.RealName}}
</td>
</tr>
<tr v-show="store.Current == index">
<td>
{{data.Username}}
</td>
<td>
{{data.UnitName}}
</td>
<td>
{{data.StateStr}}
</td>
<td>
{{data.Username}}
</td>
<td>
{{data.UnitName}}
</td>
<td>
{{data.StateStr}}
</td>
</tr>
</tbody>
</table>
`
var genhead = `
<table>
<colgroup>
<col width="12.5%"></col>
<col width="12.5%"></col>
<col width="12.5%"></col>
<col width="12.5%"></col>
<col width="12.5%"></col>
<col width="12.5%"></col>
<col width="12.5%"></col>
<col width="12.5%"></col>
</colgroup>
<tbody @click="$emit('heads')">
<tr>
<td rowspan="2">
序号
</td>
<td colspan="2">
用户名
</td>
<td >
姓名
</td>
<td rowspan="2">
序号
</td>
<td colspan="2">
用户名
</td>
<td >
姓名
</td>
</tr>
<tr v-show="head">
<td>
用户名
</td>
<td>
部门名称
</td>
<td >
状态
</td>
<td>
用户名
</td>
<td>
部门名称
</td>
<td >
状态
</td>
</tr>
</tbody>
</table>
`;
</script>
css样式:
<style>
table{
width:750px;
}
.body {
width:375px;
overflow: scroll;
}
.header {
width:375px;
overflow: scroll;
}
tr {
height:40px;
}
td {
border: 1px solid #ebeef5;
word-break: break-all;
text-align: center;
padding: 0px;
vertical-align: middle;
}
.on {
background: #F5F7FA;
}
.off {
background: white;
}
</style>
html组件:上一个的基础上不变
js(vue data不变):
js(vue methods不变):
vue之后加一个jquery函数(用于表头表体联动):
$(function () {
$('.body').on('scroll', function () {
let left = $(this).scrollLeft();
$('.header').scrollLeft(left);
});
});
效果:
六:固定第一列:
js模板:跟之前的一样
html组件:
<my-fix>
<template slot="fixhead">
<gen-head @heads="heads" :head="head"></gen-head>
</template>
<gen-body :table-data="UserArr" @bodys="bodys"></gen-body>
</my-fix>
<my-head>
<gen-head @heads="heads" :head="head" ></gen-head>
</my-head>
<my-body>
<gen-body :table-data="UserArr" @bodys="bodys"></gen-body>
</my-body>
css样式:
<style>
table{
width:750px;
}
.body {
width:375px;
overflow: scroll;
}
.header {
width:375px;
overflow: scroll;
}
tr {
height:40px;
}
td {
border: 1px solid #ebeef5;
word-break: break-all;
text-align: center;
padding: 0px;
vertical-align: middle;
}
/*用于阻止用户滑动表头*/
.header {
touch-action: pan-y;
}
.on {
background: #F5F7FA;
}
.off {
background: white;
}
.custom-table--body-wrapper {
overflow: hidden;
}
.custom-table--header-wrapper {
overflow: hidden;
}
.custom-table--fixed-wrapper {
position: absolute;
left: 3px;
/*这个值就是table距离顶部的一个距离,如果页面上有引起table位置变化的因素,那么这个值应该取一个变量和table距离顶部的高度相同,否则会错位*/
top: 123px;
bottom: 0;
background-color: #f8f8f8;
/*用于覆盖底下的table*/
z-index: 0;
width: 93px;
}
</style>
js函数:不变
效果:
七:固定多列
就变一下css样式
css样式:
.custom-table--fixed-wrapper {
position: absolute;
left: 3px;
/*这个值就是table距离顶部的一个距离,如果页面上有引起table位置变化的因素,那么这个值应该取一个变量和table距离顶部的高度相同*/
top: 123px;
bottom: 0;
background-color: #f8f8f8;
/*用于覆盖底下的table*/
z-index: 0;
/*这个值用于覆盖多少列,就是固定多少列*/
width: 280px;
}
效果
:
八:固定表头:
其他不变
添加一个jquery函数:用于调节固定的位置这些参数
$(function () {
$('.body').on('scroll', function () {
let left = $(this).scrollLeft();
$('.header').scrollLeft(left);
});
var tab_top = $('.header').offset().top;
$(window).scroll(function () {
var scroH = $(this).scrollTop();
/*35是悬浮位置距离浏览器顶部的高度*/
if (scroH > tab_top-35) {
$(".header").css("position", "fixed");
$(".custom-table--header-wrapper").css("position", "fixed");
$(".header").css("top", "35px");
$(".custom-table--header-wrapper").css("top", "35px");
/*这个数和固定列的宽度一样.custom-table--fixed-wrapper*/
$(".custom-table--header-wrapper").css("width", "95px");
/*这个颜色和之前的表头背景色要一样*/
$(".header").css("background-color", "#f8f8f8");
$(".custom-table--header-wrapper").css("background-color", "#f8f8f8");
} else {
$(".header").css("position", "relative");
$(".custom-table--header-wrapper").css("position", "relative");
}
});
});
效果:
:
时间匆忙,实现所有效果的情况,有bug,慎用:
比如,固定列和定位靠手动去写多少px,这不科学吧,
左下角穿透底部菜单了 ,从顶部往下滑,表头位置已经不对了 ,比初始下降了一点,导致表体第一行数据被遮挡:
不过这些问题,应该都是很好解决的.
组件源码(很简单就是几个div中放几个插槽):
var mybody = `
<div class="body">
<slot></slot>
</div>
`
var myhead = `
<div class="header">
<slot></slot>
</div>
`
var myfix = `
<div class="custom-table--fixed-wrapper">
<div class="custom-table--header-wrapper" >
<slot name="fixhead"></slot>
</div>
<div class="custom-table--body-wrapper">
<slot></slot>
</div>
</div>
`
var myBody = {
template: mybody,
}
;
var myHead = {
template: myhead,
}
;
var myFix = {
template: myfix,
}
;
Vue.component('my-body', myBody);
Vue.component('my-head', myHead);
Vue.component('my-fix', myFix);
Vue.component('gen-head', {
props: ["head"],
template: genhead,
});
Vue.component('gen-body', {
props: ["tableData"],
template: genbody,
});
有问题,欢迎指正批评
2019年6月7日01:09:02补充:
以上左下角穿透bug:z-index=100可解决
css样式:
<style>
table {
width: 750px;
}
.body {
width: 375px;
overflow: scroll;
/*这个值要比悬浮div小*/
z-index: -100;
}
.header {
width: 375px;
overflow: scroll;
}
tr {
height: 40px;
}
td {
border: 1px solid #ebeef5;
word-break: break-all;
text-align: center;
padding: 0px;
vertical-align: middle;
}
/*用于阻止用户滑动表头*/
.header {
touch-action: pan-y;
}
.on {
background: #F5F7FA;
}
.off {
background: white;
}
.custom-table--body-wrapper {
overflow: hidden;
}
.custom-table--header-wrapper {
overflow: hidden;
/*用于解决左下角穿透底部菜单问题*/
z-index: 99;
}
.custom-table--fixed-wrapper {
position: absolute;
left: 3px;
/*这个值就是table距离顶部的一个距离,如果页面上有引起table位置变化的因素,那么这个值应该取一个变量和table距离顶部的高度相同*/
top: 123px;
bottom: 0;
background-color: #f8f8f8;
/*用于覆盖底下的table比body大,比他上面的元素要小*/
/*这个值用于覆盖多少列,就是固定多少列*/
/*覆盖两列的宽度*/
/*width: 280px;*/
/*覆盖一列的宽度*/
width: 95px;
}
</style>
固定列遮挡第一列问题:解决代码如下:
<script>
$(function () {
$('.body').on('scroll', function () {
let left = $(this).scrollLeft();
$('.header').scrollLeft(left);
});
var tab_top = $('.header').offset().top;
$(window).scroll(function () {
var scroH = $(this).scrollTop();
/*35是悬浮位置距离浏览器顶部的高度*/
if (scroH > tab_top - 35) {
$(".header").css("position", "fixed");
$(".custom-table--header-wrapper").css("position", "fixed");
$(".header").css("top", "35px");
$(".custom-table--header-wrapper").css("top", "35px");
/*这个数和固定列的宽度一样.custom-table--fixed-wrapper*/
$(".custom-table--header-wrapper").css("width", "95px");
/*这个颜色和之前的表头背景色要一样*/
$(".header").css("background-color", "#f8f8f8");
$(".custom-table--header-wrapper").css("background-color", "#f8f8f8");
} else {
$(".header").css("position", "relative");
/*解决第一行被相对定位的表头遮挡问题*/
$(".header").css("top", "0px");
$(".custom-table--header-wrapper").css("position", "relative");
/*解决第一行被相对定位的表头遮挡问题*/
$(".custom-table--header-wrapper").css("top", "0px");
}
});
});
</script>
其他问题:
各种浏览器 ,各种 分辨率设备,兼容性问题,横屏问题,有待解决,z-inde=99解决了左下角穿透问题,设置相对定位的 top属性解决了 表头遮挡表体第一行问题,还有不能手写px问题,应该交给js去得到合适的数值,设置合适的数值,而不是手动去赋值!!!
最终效果如下:
最后故意触发那个bug,就是通过点击查询最右边那个大于号,展开了查询条件,导致表格位置发生了变化,而固定列悬浮的div,并没有感受到变化,导致错位,这也是一个bug,也就是说当页面有改变表格位置的动作时,表格固定列和表格其他部分会错位
更多推荐
所有评论(0)