<template>
|
<div class="table_box" :class="theme">
|
<div class="table_header" v-if="none">
|
<table>
|
<tr>
|
<th v-if="first" :style="{ width: firstWidth }">
|
<slot name="first-th" />
|
</th>
|
<th v-if="checkbox" class="check">
|
<span class="demo_checkbox"
|
><input
|
type="checkbox"
|
name="checkAll"
|
:id="ids + 'select-all'"
|
v-model="selectCheck" /><label
|
:for="ids + 'select-all'"
|
@click="selectAll"
|
><i></i></label
|
></span>
|
</th>
|
<th
|
v-for="(i, j) in tr"
|
:key="j + '--table-th'"
|
@click="sort(i, j)"
|
:style="i.width ? 'width:' + i.width : ''"
|
>
|
<b>{{ i.text }}</b
|
><span class="sort" v-if="i.down && !i.menu"
|
><i class="up" :class="{ active: i.table_sort === 0 }"></i
|
><i
|
class="down"
|
:class="{ active: i.table_sort === 2 }"
|
></i></span
|
><span v-if="i.down && i.menu" class="sort"
|
><i class="arrow_down" v-if="!i.menu_sort"></i
|
><i v-else class="arrow_up"></i
|
></span>
|
<dl
|
class="menu"
|
:class="{ show: i.menu_sort }"
|
v-if="i.menu"
|
@mouseenter="dlEnter(i)"
|
@mouseleave="dlLeave(i)"
|
>
|
<dd @click="menu(i, '')">全部</dd>
|
<dd
|
v-for="(s, j) in i.menu_data"
|
:key="j + '--is-dl-dd'"
|
@click="menu(i, s)"
|
>
|
{{ s.val }}
|
</dd>
|
</dl>
|
</th>
|
<th v-if="end" :style="{ width: endWidth }">
|
<slot name="end-th" />
|
</th>
|
</tr>
|
</table>
|
</div>
|
<div class="table_main" :class="{ scroll: !scroll }" :id="ids + '-scroll'">
|
<div class="b_scroll">
|
<table class="table">
|
<tr v-if="item.length < 1" class="none">
|
<td :colspan="tr.length - 1">无数据</td>
|
</tr>
|
<tr v-for="(i, l) in item" :key="l + '--td'">
|
<td v-if="first" :style="{ width: firstWidth }">
|
<slot :scope="i" name="first-td" />
|
</td>
|
<td v-if="checkbox" class="check">
|
<span class="demo_checkbox"
|
><input
|
type="checkbox"
|
name="check"
|
:checked="i.table_checked"
|
:id="ids + '-list-check-' + l" /><label
|
:for="ids + '-list-check-' + l"
|
@click="selectOnce(i)"
|
><i></i></label
|
></span>
|
</td>
|
<td
|
v-for="(s, m) in tr"
|
:key="m + '--val'"
|
:style="s.width ? 'width:' + s.width : ''"
|
>
|
<slot
|
:scope="i"
|
:name="s.slot || s.val"
|
v-if="s.val === 'btn'"
|
></slot
|
><b
|
v-else
|
:style="'color:' + (s.color ? getColor(i.table_styls, s) : '')"
|
:class="{ pointer: s.click }"
|
@click="getClick(s, i)"
|
:title="i[s.val]"
|
>{{ i[s.val] }}</b
|
>
|
</td>
|
<td v-if="end" :style="{ width: endWidth }">
|
<slot :scope="i" name="end-td" />
|
</td>
|
</tr>
|
</table>
|
</div>
|
</div>
|
</div>
|
</template>
|
|
<script>
|
export default {
|
props: {
|
trs: {
|
type: Array,
|
default: () => {
|
return [];
|
},
|
},
|
tds: {
|
type: Array,
|
default: () => {
|
return [];
|
},
|
},
|
ids: {
|
type: String,
|
default: "table-scroll-" + parseInt(Math.random() * 100000),
|
},
|
theme: { type: String, default: "member" }, // 主题
|
checkbox: { type: Boolean, default: false }, // 是否打开复选
|
timeout: { type: Number, default: 200 }, // 节流
|
scroll: { type: Boolean, default: false }, // 是否启用scroll
|
menuout: { type: Number, default: 2000 }, // menu离开状态 多少 时间隐藏
|
first: { type: Boolean, default: false },
|
firstWidth: { type: String, default: "" },
|
end: { type: Boolean, default: false },
|
endWidth: { type: String, default: "" },
|
},
|
data() {
|
return {
|
tr: [],
|
item: [],
|
none: 1,
|
checked: false,
|
tos: { x: 0, y: 0, r: 0 },
|
timer: null,
|
dlTimer: null,
|
$scroll: null,
|
selectCheck: false,
|
};
|
},
|
watch: {
|
trs: {
|
handler() {
|
this.getTrs();
|
},
|
deep: true,
|
},
|
tds: {
|
handler() {
|
// scroll 重置
|
this.tos.r++;
|
this.getTds();
|
},
|
deep: true,
|
},
|
item: {
|
handler() {
|
this.selectCheck = false;
|
},
|
deep: true,
|
},
|
},
|
methods: {
|
timers(fn) {
|
if (this.timer !== null) {
|
return false;
|
}
|
this.timer = setTimeout(() => {
|
fn();
|
clearTimeout(this.timer);
|
this.timer = null;
|
}, this.timeout);
|
},
|
getColor(a, s) {
|
let b = s.table_status;
|
if (!Array.isArray(b) || b.length < 1 || a[s.val] === undefined) {
|
return "";
|
}
|
let y = {};
|
b.forEach((k) => {
|
if (k.val * 1 === a[s.val] * 1) {
|
y = k;
|
}
|
});
|
if (y.val >= 0) return y.key;
|
return "";
|
},
|
getTrs() {
|
let x = this.trs;
|
if (Array.isArray(x) && x.length > 0) {
|
let y = [];
|
x.forEach((k, v) => {
|
if (k.sort === undefined) {
|
k.sort = v;
|
}
|
if (k.down === undefined) {
|
k.down = false;
|
}
|
if (k.menu === undefined) {
|
k.menu = false;
|
}
|
k.tr_id = v;
|
k.menu_sort = 0;
|
k.table_sort = 1;
|
y.push(k);
|
});
|
y.sort((a, b) => {
|
return a.sort - b.sort;
|
});
|
this.tr = y;
|
this.none = 1;
|
} else {
|
this.none = 0;
|
}
|
},
|
getTds(n = 0) {
|
let x = this.tds;
|
if (!n) {
|
this.item = [];
|
}
|
let y = [];
|
if (Array.isArray(x) && x.length > 0) {
|
x.forEach((k, v) => {
|
k.table_id = v;
|
k.table_checked = 0;
|
k.table_styls = k.styls || {};
|
y.push(k);
|
});
|
if (!n) {
|
this.item = y;
|
}
|
}
|
if (n) {
|
return y;
|
}
|
},
|
menu(i, s) {
|
this.timers(() => {
|
i.menu_sort = !i.menu_sort;
|
if (s === "" || s.val === "") {
|
this.getTds();
|
return false;
|
}
|
let sx = this.getTds(1);
|
this.item = sx.filter((k) => {
|
return s.val === k[i.val];
|
});
|
this.tos.r++;
|
});
|
},
|
sort(i) {
|
this.timers(() => {
|
if (i.menu) {
|
i.menu_sort = !i.menu_sort;
|
this.tr.push([]);
|
this.tr.splice(this.tr.length - 1, 1);
|
this.dlLeave(i);
|
return false;
|
}
|
// console.log(i.down, i.val, i.table_sort);
|
if (i.down) {
|
let x = this.item;
|
if (i.table_sort === 1) {
|
// down
|
x.sort((a, b) => {
|
if (!isNaN(a[i.val]) && !isNaN(b[i.val])) {
|
return a[i.val] - b[i.val];
|
}
|
return (a[i.val] + "").localeCompare(b[i.val] + "");
|
});
|
i.table_sort = 2;
|
} else if (i.table_sort === 2) {
|
// up
|
x.sort((a, b) => {
|
if (!isNaN(a[i.val]) && !isNaN(b[i.val])) {
|
return b[i.val] - a[i.val];
|
}
|
return (b[i.val] + "").localeCompare(a[i.val] + "");
|
});
|
i.table_sort = 0;
|
} else {
|
// quxiao
|
x.sort((a, b) => {
|
return a.table_id - b.table_id;
|
});
|
i.table_sort = 1;
|
}
|
this.tos.r++;
|
}
|
});
|
},
|
dltimers(fn) {
|
if (this.dlTimer !== null) {
|
clearTimeout(this.dlTimer);
|
this.dlTimer = null;
|
this.dltimers(fn);
|
return false;
|
}
|
this.dlTimer = setTimeout(() => {
|
fn();
|
clearTimeout(this.dlTimer);
|
this.dlTimer = null;
|
}, this.menuout);
|
},
|
dlEnter(i) {
|
clearTimeout(this.dlTimer);
|
this.dlTimer = null;
|
if (!i.menu_sort) {
|
i.menu_sort = true;
|
this.tr.push([]);
|
this.tr.splice(this.tr.length - 1, 1);
|
}
|
},
|
dlLeave(i) {
|
this.dltimers(() => {
|
if (i.menu_sort) {
|
i.menu_sort = false;
|
this.tr.push([]);
|
this.tr.splice(this.tr.length - 1, 1);
|
}
|
});
|
},
|
selectAll() {
|
this.checked = !this.checked;
|
let _data = this.item;
|
this.item = [];
|
_data.forEach((k) => {
|
k.table_checked = !k.table_checked;
|
});
|
this.item = _data;
|
this.checkSelect();
|
},
|
selectOnce(i) {
|
this.timers(() => {
|
let c = this.item.indexOf(i);
|
let x = this.item;
|
if (c >= 0) {
|
x[c].table_checked = !x[c].table_checked;
|
}
|
this.item = [];
|
this.item = x;
|
this.checkSelect();
|
});
|
},
|
checkSelect() {
|
this.$nextTick(() => {
|
let y = [];
|
this.item.forEach((k) => {
|
if (k.table_checked) {
|
y.push(k);
|
}
|
});
|
this.$emit("checked", y);
|
});
|
},
|
getClick(i, s) {
|
if (demo && demo.version && document.execCommand("copy")) {
|
demo.$ctrl.c("", s[i.val]);
|
demo.alert("复制成功", 1);
|
}
|
if (!i.click) return false;
|
this.$emit("clicked", { type: i.val, value: s[i.val], data: s });
|
},
|
},
|
mounted() {
|
this.getTrs();
|
this.getTds();
|
this.$nextTick(() => {
|
if (this.scroll && demo) {
|
this.$scroll = demo.scroll("#" + this.ids + "-scroll", { bar: true });
|
this.$emit("scrollFinish", this.$scroll);
|
}
|
});
|
},
|
};
|
</script>
|
<style lang='less' scoped>
|
.table_box {
|
width: 100%;
|
height: 100%;
|
overflow: hidden;
|
}
|
.table_box .check {
|
width: 40px;
|
}
|
.table_box .check .demo_checkbox input[type="checkbox"] + label,
|
.table_box .check .demo_checkbox input[type="radio"] + label {
|
height: 20px;
|
line-height: 20px;
|
transform: translateY(-2px);
|
}
|
.table_box .table_header tr th {
|
position: relative;
|
overflow: visible;
|
}
|
.table_box .table_flex {
|
display: flex;
|
flex-wrap: wrap;
|
padding: 5px 0;
|
text-align: center;
|
justify-content: center;
|
}
|
.table_box .table_flex .span,
|
.table_box .table_flex span {
|
line-height: 1;
|
font-size: 14px;
|
text-decoration: underline;
|
margin: 2px 5px;
|
word-wrap: break-word;
|
word-break: break-all;
|
cursor: pointer;
|
opacity: 0.8;
|
}
|
.table_box .table_flex .span:hover,
|
.table_box .table_flex span:hover {
|
opacity: 1;
|
}
|
.table_box .sort {
|
position: relative;
|
}
|
.table_box .sort .down,
|
.table_box .sort .up {
|
width: 0;
|
height: 0;
|
border: 5px solid transparent;
|
box-sizing: border-box;
|
position: absolute;
|
left: 5px;
|
top: 0;
|
}
|
.table_box .sort .arrow_down,
|
.table_box .sort .arrow_up {
|
position: absolute;
|
left: 5px;
|
top: 0;
|
bottom: 0;
|
margin: auto;
|
width: 7px;
|
height: 7px;
|
border: 2px solid transparent;
|
box-sizing: border-box;
|
border-top-color: #222;
|
border-left-color: #222;
|
transition: all 0.2s;
|
}
|
.table_box .sort .up {
|
border-top-color: rgba(255, 255, 255, 0.5);
|
top: 11px;
|
}
|
.table_box .sort .down {
|
transform: rotate(180deg);
|
border-top-color: rgba(255, 255, 255, 0.5);
|
top: -1px;
|
}
|
.table_box .sort .active {
|
border-top-color: #57ccdf;
|
}
|
.table_box .sort .arrow_down {
|
transform: rotate(-135deg) translateX(2px);
|
}
|
.table_box .sort .arrow_up {
|
transform: rotate(45deg) translateY(3px);
|
}
|
.table_box .menu {
|
position: absolute;
|
left: 0;
|
right: 0;
|
margin: auto;
|
top: 100%;
|
width: 100%;
|
background-color: #fff;
|
z-index: 333;
|
max-width: 150px;
|
border-bottom-right-radius: 5px;
|
border-bottom-left-radius: 5px;
|
transform: translateX(-50%) scale(0);
|
opacity: 0;
|
transition: all 0.3s;
|
}
|
.table_box .menu.show {
|
transform: translateX(0) scale(1);
|
opacity: 1;
|
}
|
.table_box .menu:hover {
|
box-shadow: 0 0 10px #eee;
|
}
|
.table_box .menu dd {
|
line-height: 40px;
|
height: 40px;
|
border-bottom: 1px solid #eee;
|
font-size: 16px;
|
font-weight: 400;
|
color: #333;
|
}
|
.table_box .menu dd:last-child {
|
border: 0;
|
}
|
.table_box.mini .table_header {
|
height: 30px;
|
line-height: 30px;
|
z-index: 300;
|
}
|
.table_box.mini tr {
|
height: 30px;
|
line-height: 30px;
|
font-size: 12px;
|
font-weight: 400;
|
}
|
.table_box.mini tr th {
|
height: 30px;
|
cursor: pointer;
|
}
|
.table_box.mini tr .pointer {
|
cursor: pointer;
|
}
|
.table_box.mini .table_main {
|
height: calc(100% - 30px);
|
z-index: 299;
|
overflow: hidden;
|
position: relative;
|
}
|
.table_box.mini .table_main.scroll {
|
overflow-y: auto;
|
}
|
.table_box.mini .table_header {
|
background: linear-gradient(45deg, #25457a, #56698a);
|
}
|
.table_box.white .table_header {
|
height: 32px;
|
line-height: 32px;
|
z-index: 300;
|
}
|
.table_box.white tr {
|
height: 32px;
|
line-height: 32px;
|
font-size: 14px;
|
font-weight: 400;
|
}
|
.table_box.white tr th {
|
height: 32px;
|
cursor: pointer;
|
}
|
.table_box.white tr .pointer {
|
cursor: pointer;
|
}
|
.table_box.white .table_main {
|
height: calc(100% - 32px);
|
z-index: 299;
|
overflow: hidden;
|
position: relative;
|
}
|
.table_box.white .table_main.scroll {
|
overflow-y: auto;
|
}
|
.table_box.white tr td,
|
.table_box.white tr th {
|
color: #666;
|
}
|
.table_box.white .table_header tr {
|
border-bottom: 1px solid #f0f0f0;
|
}
|
.table_box.white .check .checkbox input + b {
|
border-color: #57ccdf;
|
border-radius: 5px;
|
}
|
.table_box.member {
|
.table_header {
|
height: 42px;
|
line-height: 42px;
|
z-index: 300;
|
}
|
tr {
|
height: 42px;
|
line-height: 42px;
|
z-index: 400;
|
font-size: 13px;
|
th {
|
height: 42px;
|
cursor: pointer;
|
color: #222;
|
font-size: 13px;
|
font-weight: 700;
|
border: 1px solid #ccc;
|
border-bottom: 0;
|
}
|
td {
|
color: #222;
|
border: 1px solid #ccc;
|
b {
|
display: block;
|
white-space: pre-wrap;
|
line-height: 1.2;
|
}
|
}
|
&.pointer {
|
cursor: pointer;
|
}
|
}
|
.table_main {
|
height: calc(100% - 42px);
|
z-index: 299;
|
overflow: hidden;
|
position: relative;
|
&.scroll {
|
overflow-y: auto;
|
}
|
}
|
.table_header {
|
background-color: #f2f2f2;
|
}
|
}
|
.table_box.task .table_header {
|
height: 77px;
|
line-height: 77px;
|
z-index: 300;
|
}
|
.table_box.task tr {
|
height: 77px;
|
line-height: 77px;
|
font-size: 16px;
|
font-weight: 400;
|
}
|
.table_box.task tr th {
|
height: 77px;
|
cursor: pointer;
|
}
|
.table_box.task tr .pointer {
|
cursor: pointer;
|
}
|
.table_box.task .table_main {
|
height: calc(100% - 77px);
|
z-index: 299;
|
overflow: hidden;
|
position: relative;
|
}
|
.table_box.task .table_main.scroll {
|
overflow-y: auto;
|
}
|
.table_box.task tr th {
|
color: #222;
|
font-size: 18px;
|
font-weight: 700;
|
}
|
.table_box.task tr td {
|
color: #222;
|
}
|
.table_box.task .table_header tr {
|
border-top: 0;
|
background-color: #e6e6e6;
|
}
|
.table_box.task .table_main tr:nth-child(2n) {
|
background-color: #f5f5f5;
|
}
|
.table_box.task .table_main tr:nth-child(2n + 1) {
|
background-color: #fff;
|
}
|
.table_xlsx_down {
|
position: absolute;
|
left: 0;
|
right: 0;
|
bottom: 0;
|
top: 0;
|
margin: auto;
|
width: 50%;
|
height: 50%;
|
background-color: #eee;
|
box-shadow: 0 0 10px #333;
|
border-radius: 5px;
|
box-sizing: border-box;
|
overflow: hidden;
|
min-width: 350px;
|
max-width: 500px;
|
z-index: 1000;
|
transition: all 0.3s;
|
}
|
.table_xlsx_down header {
|
position: relative;
|
height: 35px;
|
line-height: 34px;
|
border-bottom: 1px solid #333;
|
box-sizing: border-box;
|
padding: 0 10px;
|
font-size: 15px;
|
font-weight: 700;
|
}
|
.table_xlsx_down header .close {
|
position: absolute;
|
right: 0;
|
top: 0;
|
height: 34px;
|
width: 34px;
|
text-align: center;
|
color: rgba(255, 123, 123, 0.7);
|
cursor: pointer;
|
font-size: 20px;
|
background-color: #eee;
|
}
|
.table_xlsx_down .foot {
|
height: 40px;
|
text-align: center;
|
box-sizing: border-box;
|
padding: 4px;
|
}
|
.table_xlsx_down .foot button {
|
min-width: 80px;
|
}
|
.table_xlsx_down .main {
|
position: relative;
|
height: calc(100% - 75px);
|
display: flex;
|
}
|
.table_xlsx_down .main .l,
|
.table_xlsx_down .main .r {
|
width: 50%;
|
height: 100%;
|
box-sizing: border-box;
|
}
|
.table_xlsx_down .main .l li,
|
.table_xlsx_down .main .r li {
|
line-height: 30px;
|
text-overflow: ellipsis;
|
overflow: hidden;
|
white-space: nowrap;
|
box-sizing: border-box;
|
padding: 0 10px 2px;
|
}
|
.table_xlsx_down .main .l li + li,
|
.table_xlsx_down .main .r li + li {
|
border-top: 1px solid #ccc;
|
}
|
.table_xlsx_down .main .l li .demo_checkbox input[type="checkbox"] + label,
|
.table_xlsx_down .main .l li .demo_checkbox input[type="radio"] + label,
|
.table_xlsx_down .main .r li .demo_checkbox input[type="checkbox"] + label,
|
.table_xlsx_down .main .r li .demo_checkbox input[type="radio"] + label {
|
height: 30px;
|
line-height: 30px;
|
}
|
.table_xlsx_down .main .all {
|
margin-left: 10px;
|
}
|
.table_xlsx_down .main .scroll {
|
height: 100%;
|
}
|
.table_xlsx_down .main span + .scroll {
|
height: calc(100% - 40px);
|
position: relative;
|
overflow: hidden;
|
}
|
.table_xlsx_down .main .r {
|
border-left: 2px dashed #00bfff;
|
}
|
.table_xlsx_down .main .r li {
|
position: relative;
|
padding-right: 60px;
|
font-size: 13px;
|
}
|
.table_xlsx_down .main .r li .icon {
|
position: absolute;
|
top: 0;
|
bottom: 0;
|
margin: auto;
|
width: 30px;
|
height: 30px;
|
text-align: center;
|
line-height: 30px;
|
font-size: 22px;
|
cursor: pointer;
|
color: #333;
|
}
|
.table_xlsx_down .main .r li .down {
|
right: 0;
|
transform: rotate(-90deg);
|
}
|
.table_xlsx_down .main .r li .up {
|
right: 30px;
|
transform: rotate(90deg);
|
}
|
.table_xlsx_down .main .r li .dis {
|
color: #ccc;
|
}
|
.table_xlsx_down .main .r li:nth-child(2n + 1) {
|
background-color: #ccc;
|
}
|
</style>
|