组件<template><!-- fy自定义表格 --><div class="fy-table-diy-wrap"><table class="fy-table-multi-column-wrap" v-infinite-scroll="loadMore"><thead class="fy-table-multi-thead radius-ten"><tr class="status-info" v-show="isShowStatusInfo"><th colspan="5"><span class="order-status-wrap"><i class="cancel-order"></i>取消订单</span><span class="order-status-wrap"><i class="intention-order"></i>意向订单</span><span class="order-status-wrap"><i class="formal-order"></i>正式订单</span></th></tr><tr class="header-bg"><slot name="header"></slot></tr></thead><!-- 置顶表格 --><slot name="sticky"></slot><!-- tbody --><slot></slot><tfoot class="fy-table-multi-column-footer"><tr v-if="tableDataList.length !== 0"></tr><tr v-else><td :colspan="headDataList.length">暂无数据</td></tr></tfoot></table><!-- 鼠标右键菜单 --><div><ul class="menu" id="menuId" v-show="isShowRightMenu"><li@click="handleClickTop(getTopList)"class="menu-item icon-right-arrow"v-show="isShowTop"><i class="menu-item-bg"></i>置顶</li><li@click="handleClickCancel(cancelIndex)"class="menu-item icon-right-arrow"v-show="isShowTop"><i class="menu-item-bg"></i>取消置顶</li><li:key="index"@click="clickEvent(iterm.fnName)"class="menu-item icon-right-arrow"v-for="(iterm,index) in rowClickMenus"><i class="menu-item-bg"></i>{{iterm.text}}<span class="right-arrow" v-show="iterm.secondaryMenu"></span><ul class="secondary-menu"><li:key="index"@click="clickEvent(item)"class="menu-item"v-for="(item,index) in iterm.secondaryMenu"><i class="menu-item-bg"></i>{{item}}</li></ul></li></ul></div></div></template><script>export default {name: 'fyCustomTable',data() {return {}},props: {// 是否展示状态信息isShowStatusInfo: {type: Boolean,default: false,},// 列表数据tableDataList: {type: Array,default: function() {return []},},// 表头列的数据headDataList: {type: Array,default: function() {return []},},// 是否显示右键菜单isShowRightMenu: {type: Boolean,default: false,},// 右键菜单数据rowClickMenus: {type: Array,},// 表格置顶数据getTopList: {type: Object,},// 是否显示表格置顶isShowTop: {type: Boolean,default: false,},// 取消置顶的索引cancelIndex: {type: Number,default: null,},},methods: {loadMore() {this.$emit('load-more')},// 分发右键菜单的点击事件出去clickEvent(val) {if (val) {this.$emit('right-menu-click-event', val)}},// 置顶方法handleClickTop(val) {this.$emit('handle-click-top', val)},// 取消置顶方法handleClickCancel(val) {this.$emit('handle-click-cancel', val)},},}</script><style lang="scss">.fy-table-diy-wrap {width: 100%;height: 100%;overflow-x: auto;.fy-table-multi-column-wrap {width: 100%;height: calc(100% - 175px);box-sizing: border-box;background: $color-fff;border-radius: 10px;border-collapse: collapse;white-space: nowrap;.fy-table-multi-thead {box-shadow: 0px 1px 0px 0px rgba(230, 230, 230, 1);tr {height: 40px;// 状态信息&.status-info {text-align: left;.order-status-wrap {margin-right: 30px;.cancel-order,.intention-order,.formal-order {display: inline-block;width: 20px;height: 10px;margin-right: 10px;}// 取消订单.cancel-order {background: rgba(238, 239, 240, 1);box-shadow: 0px 2px 4px 0px rgba(0, 0, 0, 0.2);border-radius: 2px;}// 意向订单.intention-order {background: rgba(252, 244, 148, 1);box-shadow: 0px 2px 4px 0px rgba(181, 154, 63, 0.4);border-radius: 2px;}// 正式订单.formal-order {background: rgba(255, 255, 255, 1);box-shadow: 0px 1px 4px 0px rgba(0, 0, 0, 0.3);border-radius: 2px;}}}&.header-bg {@include themify() {background: themed('table-header-background-color');}}th {padding: 0 22px;font-size: $font-size-14;font-weight: $font-weight-600;color: $color-333;text-align: left;&:first-child {padding-left: 30px;}&:last-child {padding-right: 30px;}}}}.fy-table-multi-tbody-wrap {.collapse-tr {td {&:first-child {padding-left: 30px;}&:last-child {padding-right: 30px;}}}.fy-table-multi-tr {td {padding: 0 22px;padding-bottom: 6px;font-size: $font-size-14;color: $color-333;text-align: left;&:first-child {padding-left: 30px;}&:last-child {padding-right: 30px;}}}.fy-table-multi-title {padding-top: 8px;white-space: nowrap;overflow: hidden;text-overflow: ellipsis;}tr:nth-child(2n) {padding: 10px 0;box-shadow: 0px 1px 0px 0px rgba(230, 230, 230, 1);}}// tfoot.fy-table-multi-column-footer {tr {text-align: center;height: 16px;}}}// 对齐方式.text-right {padding: 0 50px;text-align: right !important;}.text-left {text-align: left !important;}.menu {position: fixed;z-index: 999;box-sizing: border-box;font-size: $font-size-14;font-weight: $font-weight-400;border-radius: 2px;-webkit-border-radius: 2px;-moz-border-radius: 2px;-ms-border-radius: 2px;-o-border-radius: 2px;@include themify() {background: themed('right-click-menu-bg');border: 1px solid rgba(128, 128, 128, 0.5);border-radius: 2px;}.menu-item {display: block;position: relative;box-sizing: border-box;-moz-box-sizing: border-box;-webkit-box-sizing: border-box;min-width: 158px;line-height: 28px;padding-left: 40px;position: relative;@include themify() {color: themed('table-font-color');}cursor: pointer;.menu-item-bg {position: absolute;left: 30px;top: 0;display: block;width: 1px;height: 30px;background-color: #f0f0f2;}//分组最后一个菜单选项的样式&.menu-last-item {background: url(~@img/table/right-click-bottom.png) 30px no-repeat;}//二级菜单.secondary-menu {display: none;position: absolute;left: 160px;top: 0;@include themify() {background: themed('right-click-menu-bg');box-shadow: 4px 4px 6px themed('form-no-checked-line-color');}.menu-item {display: block;box-sizing: border-box;}}&.icon-right-arrow {position: relative;.menu-item-text {font-size: $font-size-14;@include themify() {color: themed('table-font-color');}}// 右侧箭头小图标.right-arrow {position: absolute;right: 10px;bottom: 9px;display: inline-block;width: 0;height: 0;border-top: 5px solid transparent;border-bottom: 5px solid transparent;@include themify() {border-left: 5px solid themed('table-font-color');}}}&:hover {box-sizing: border-box;z-index: 1020;@include themify() {background: themed('right-click-menu-hover-bg');box-shadow: 1px 1px 2px themed('right-click-menu-hover-shadow'),-1px -1px 2px themed('right-click-menu-hover-shadow');}.secondary-menu {display: block;.menu-item:hover {box-sizing: border-box;display: block;@include themify() {background: themed('right-click-menu-hover-bg');box-shadow: 1px 1px 2px themed('right-click-menu-hover-shadow') -1px -1px2px themed(' right-click-menu-hover-shadow');}}}}}}}</style>
index.vue demo 实例
<template><div><fy-custom-table:isShowStatusInfo="true":cancel-index="cancelIndex":get-top-list="getTopList":head-data-list="headList":is-show-right-menu="isShowRightMenus":is-show-top="isShowTop":rowClickMenus="clickMenus":table-data-list="tbodyList"@handle-click-cancel="handleClickCancel"@handle-click-top="handleClickTop"@load-more="loadMore"@right-menu-click-event="rightMenuClickEvent"><!-- 表头的数据 --><template slot="header"><th:class="getTdTextAlign(index+1)":key="`1${index}`":width="getTdWidth(index + 1)"v-for="(item, index) in headList">{{item.columnName}}</th></template><!-- 表格置顶数据 --><template slot="sticky"><tbody:key="`2${index}`"@click="handleClick(index)"@contextmenu.prevent="rightClick(item,index)"class="fy-table-multi-tbody-wrap top-color"v-for="(item,index) in topDataList"><tr class="collapse-tr"><td class="href-text-color fy-table-multi-title" colspan="7">{{item.title}}</td></tr><tr class="fy-table-multi-tr"><td>{{item.startPlace}}</td><td>{{item.desPlace}}</td><td>{{item.joinType}}</td><td>{{item.planNum}}</td><td class="text-right">{{item.prices}}</td><td>{{item.tag}}</td><td>{{item.word}}</td></tr></tbody></template><!-- 列表中数据 --><tbody:class="[getHightRowColor(item,index+1),isActive==index ? 'table-hightline-color' : '']":key="index"@click="handleClick(index)"@contextmenu.prevent="rightClick(item,index)"class="fy-table-multi-tbody-wrap"v-for="(item,index) in tbodyList"><tr class="collapse-tr"><td class="href-text-color fy-table-multi-title" colspan="7">{{item.title}}</td></tr><tr class="fy-table-multi-tr"><td>{{item.startPlace}}</td><td>{{item.desPlace}}</td><td>{{item.joinType}}</td><td>{{item.planNum}}</td><td class="text-right">{{item.prices}}</td><td>{{item.tag}}</td><td>{{item.word}}</td></tr></tbody></fy-custom-table></div></template><script>export default {name: 'index',data() {return {isActive: null, // 是否显示高亮当前行isShowRightMenus: false, // 是否显示右键菜单isShowTop: true, // 是否显示表格置顶getTopList: {}, // 获取置顶数据topDataList: [],clickMenus: [{text: '删除',fnName: 'delete',},],cancelIndex: null, // 取消置顶方法headList: [{columnName: '出发地',},{columnName: '目的地',},{columnName: '参团方式',},{columnName: '产品编号',},{columnName: '价格',},{columnName: '标签',},{columnName: '文档',},],tbodyList: [{id: 1,title:'【品质】新西兰南北岛12天完美穿越之旅,新西兰南北岛12天完美穿越之旅,新西兰南北岛12天完美穿越之旅新西兰【品质】新西兰南北岛12天完美穿越之旅',startPlace: '深圳',desPlace: '新西兰',joinType: '出发地参团',planNum: 'XYGL',prices: '¥3,0000',tag: '出镜',word: '行',},{id: 2,title:'【品质】新西兰南北岛12天完美穿越之旅,新西兰南北岛12天完美穿越之旅,新西兰南北岛12天完美穿越之旅新西兰',startPlace: '深圳',desPlace: '新西兰',joinType: '出发地参团',planNum: 'XYGL',prices: '¥3,0000',tag: '出镜',word: '行',},{id: 3,title:'【品质】新西兰南北岛12天完美穿越之旅,新西兰南北岛12天完美穿越之旅,新西兰南北岛12天完美穿越之旅新西兰',startPlace: '深圳',desPlace: '新西兰',joinType: '出发地参团',planNum: 'XYGL',prices: '¥3,0000',tag: '出镜',word: '行',},{id: 4,title:'【品质】新西兰南北岛12天完美穿越之旅,新西兰南北岛12天完美穿越之旅,新西兰南北岛12天完美穿越之旅新西兰',startPlace: '深圳',desPlace: '新西兰',joinType: '出发地参团',planNum: 'XYGL',prices: '¥3,0000',tag: '出镜',word: '行',},{id: 5,title:'【品质】新西兰南北岛12天完美穿越之旅,新西兰南北岛12天完美穿越之旅,新西兰南北岛12天完美穿越之旅新西兰',startPlace: '深圳',desPlace: '新西兰',joinType: '出发地参团',planNum: 'XYGL',prices: '¥3,0000',tag: '出镜',word: '行',},{id: 6,title:'【品质】新西兰南北岛12天完美穿越之旅,新西兰南北岛12天完美穿越之旅,新西兰南北岛12天完美穿越之旅新西兰',startPlace: '深圳',desPlace: '新西兰',joinType: '出发地参团',planNum: 'XYGL',prices: '¥3,0000',tag: '出镜',word: '行',},{id: 7,title:'【品质】新西兰南北岛12天完美穿越之旅,新西兰南北岛12天完美穿越之旅,新西兰南北岛12天完美穿越之旅新西兰',startPlace: '深圳',desPlace: '新西兰',joinType: '出发地参团',planNum: 'XYGL',prices: '¥3,0000',tag: '出镜',word: '行',},{id: 8,title:'【品质】新西兰南北岛12天完美穿越之旅,新西兰南北岛12天完美穿越之旅,新西兰南北岛12天完美穿越之旅新西兰',startPlace: '深圳',desPlace: '新西兰',joinType: '出发地参团',planNum: 'XYGL',prices: '¥3,0000',tag: '出镜',word: '行',},{id: 9,title:'【品质】新西兰南北岛12天完美穿越之旅,新西兰南北岛12天完美穿越之旅,新西兰南北岛12天完美穿越之旅新西兰',startPlace: '深圳',desPlace: '新西兰',joinType: '出发地参团',planNum: 'XYGL',prices: '¥3,0000',tag: '出镜',word: '行',},{id: 10,title:'【品质】新西兰南北岛12天完美穿越之旅,新西兰南北岛12天完美穿越之旅,新西兰南北岛12天完美穿越之旅新西兰',startPlace: '深圳',desPlace: '新西兰',joinType: '出发地参团',planNum: 'XYGL',prices: '¥3,0000',tag: '出镜',word: '行',},{id: 11,title:'【品质】新西兰南北岛12天完美穿越之旅,新西兰南北岛12天完美穿越之旅,新西兰南北岛12天完美穿越之旅新西兰',startPlace: '深圳',desPlace: '新西兰',joinType: '出发地参团',planNum: 'XYGL',prices: '¥3,0000',tag: '出镜',word: '行',},{id: 12,title:'【品质】新西兰南北岛12天完美穿越之旅,新西兰南北岛12天完美穿越之旅,新西兰南北岛12天完美穿越之旅新西兰',startPlace: '深圳',desPlace: '新西兰',joinType: '出发地参团',planNum: 'XYGL',prices: '¥3,0000',tag: '出镜',word: '行',},{id: 13,title:'【品质】新西兰南北岛12天完美穿越之旅,新西兰南北岛12天完美穿越之旅,新西兰南北岛12天完美穿越之旅新西兰',startPlace: '深圳',desPlace: '新西兰',joinType: '出发地参团',planNum: 'XYGL',prices: '¥3,0000',tag: '出镜',word: '行',},{id: 14,title:'【品质】新西兰南北岛12天完美穿越之旅,新西兰南北岛12天完美穿越之旅,新西兰南北岛12天完美穿越之旅新西兰',startPlace: '深圳',desPlace: '新西兰',joinType: '出发地参团',planNum: 'XYGL',prices: '¥3,0000',tag: '出镜',word: '行',},{id: 15,title:'【品质】新西兰南北岛12天完美穿越之旅,新西兰南北岛12天完美穿越之旅,新西兰南北岛12天完美穿越之旅新西兰',startPlace: '深圳',desPlace: '新西兰',joinType: '出发地参团',planNum: 'XYGL',prices: '¥3,0000',tag: '出镜',word: '行',},],}},methods: {loadMore() {console.log('触底加载更多')},rightMenuClickEvent(val) {console.log(val, '右键菜单的点击事件')},// 选中当前行高亮颜色getHightRowColor(row, index) {if (index == 1) {// 表格高亮行颜色值return 'table-hightline-color'} else if (index == 3) {return 'intention-order-status' // 意向订单状态} else if (index == 5) {return 'cancel-order-status' // 取消订单}},clickEvent(val, index) {console.log(val, index, '点击事件')},// 右键菜单rightClick(obj, valIndex) {var menu = document.querySelector('#menuId')menu.style.left = event.pageX + 'px'menu.style.top = event.pageY + 'px'this.isShowRightMenus = truethis.isActive = valIndexthis.getTopList = obj},// 设置宽度getTdWidth(val) {// if (val == 1) {// return '45px'// }},// 对齐方法getTdTextAlign(val) {if (val == 5) {return 'text-right'}},// 点击线路产品标题展开第二列handleClick(val) {this.isActive = val},// 置顶方法handleClickTop(val) {this.isShowRightMenus = falsethis.isShowTop = falsethis.topDataList.push(val)},// 取消置顶方法handleClickCancel(val) {this.isShowRightMenus = falsethis.topDataList.splice(val, 1)},},}</script><style lang="scss" ></style>