|
@@ -1,14 +1,13 @@
|
|
|
<template>
|
|
|
<div class="table-layout">
|
|
|
<!-- 表头 -->
|
|
|
- <ul class="t-header" :class="{'bottom-line':showLine}">
|
|
|
+ <ul class="t-header" :class="{ 'bottom-line': showLine }">
|
|
|
<!-- 复选框 -->
|
|
|
<div
|
|
|
v-show="selection && !isAllSelected"
|
|
|
class="checkbox inactive"
|
|
|
@click="onClickSelectAll"
|
|
|
- >
|
|
|
- </div>
|
|
|
+ ></div>
|
|
|
<img
|
|
|
v-show="isAllSelected"
|
|
|
class="checkbox active"
|
|
@@ -18,15 +17,17 @@
|
|
|
/>
|
|
|
<!-- 表头各项 -->
|
|
|
<li
|
|
|
- v-for="(headerItem,i) in header"
|
|
|
+ v-for="(headerItem, i) in header"
|
|
|
:key="i"
|
|
|
:style="{
|
|
|
textAlign: headerItem.textAlign,
|
|
|
- width: headerItem.width ? headerItem.width+'px' : (100/header.length)+'%'
|
|
|
+ width: headerItem.width
|
|
|
+ ? headerItem.width + 'px'
|
|
|
+ : 100 / header.length + '%',
|
|
|
}"
|
|
|
>
|
|
|
<!-- 名字叫header的作用域插槽,通过headerItem作用域提供表头各项 -->
|
|
|
- <slot :headerItem='headerItem' name='header'></slot>
|
|
|
+ <slot :headerItem="headerItem" name="header"></slot>
|
|
|
</li>
|
|
|
</ul>
|
|
|
<!-- 表格内容区域 -->
|
|
@@ -40,18 +41,18 @@
|
|
|
<!-- 表格每一行 -->
|
|
|
<ul
|
|
|
class="t-item"
|
|
|
- :class="{'bottom-line': showLine}"
|
|
|
+ :class="{ 'bottom-line': showLine }"
|
|
|
v-for="(lineData, i) in data"
|
|
|
:key="i"
|
|
|
>
|
|
|
<!-- 复选框 -->
|
|
|
<div
|
|
|
- v-show="selection && !selectedIdList.some(id => id === lineData.id)"
|
|
|
+ v-show="selection && !selectedIdList.some((id) => id === lineData.id)"
|
|
|
class="checkbox inactive"
|
|
|
@click="selectItem(lineData, i)"
|
|
|
/>
|
|
|
<img
|
|
|
- v-show="selection && selectedIdList.some(id => id === lineData.id)"
|
|
|
+ v-show="selection && selectedIdList.some((id) => id === lineData.id)"
|
|
|
class="checkbox active"
|
|
|
@click="selectItem(lineData, i)"
|
|
|
src="@/assets/images/icons/checkbox.png"
|
|
@@ -60,23 +61,25 @@
|
|
|
<!-- 表格各项 -->
|
|
|
<li
|
|
|
v-for="(headerItem, j) in header"
|
|
|
- :key='j'
|
|
|
+ :key="j"
|
|
|
:style="{
|
|
|
textAlign: lineData.textAlign,
|
|
|
- width: headerItem.width ? headerItem.width + 'px' : (100 / header.length) + '%'
|
|
|
+ width: headerItem.width
|
|
|
+ ? headerItem.width + 'px'
|
|
|
+ : 100 / header.length + '%',
|
|
|
}"
|
|
|
:class="{
|
|
|
themetxt: headerItem.fontweight,
|
|
|
- showWhenHover: headerItem.showWhenHover
|
|
|
+ showWhenHover: headerItem.showWhenHover,
|
|
|
}"
|
|
|
:title="headerItem.key === 'name' ? lineData[headerItem.key] : ''"
|
|
|
>
|
|
|
<!-- 名字叫tableItem的作用域插槽,通过itemData作用域把这一项表格数据向外暴露,通过lineData作用域把每一行向外暴露,通过headerItem作用域把这一项对应的表头项向外暴露 -->
|
|
|
<slot
|
|
|
- :itemData='lineData[headerItem.key]'
|
|
|
+ :itemData="lineData[headerItem.key]"
|
|
|
:lineData="lineData"
|
|
|
- :headerItem='headerItem'
|
|
|
- name='tableItem'
|
|
|
+ :headerItem="headerItem"
|
|
|
+ name="tableItem"
|
|
|
></slot>
|
|
|
</li>
|
|
|
</ul>
|
|
@@ -85,17 +88,17 @@
|
|
|
</template>
|
|
|
|
|
|
<script>
|
|
|
-import { mapState } from 'vuex'
|
|
|
+import { mapState } from "vuex";
|
|
|
|
|
|
export default {
|
|
|
props: {
|
|
|
canRequestMoreData: {
|
|
|
type: Boolean,
|
|
|
- default: true
|
|
|
+ default: true,
|
|
|
},
|
|
|
data: {
|
|
|
type: Array,
|
|
|
- default: Array
|
|
|
+ default: Array,
|
|
|
},
|
|
|
/**
|
|
|
* 表头数据:各列名称和配置
|
|
@@ -107,97 +110,115 @@ export default {
|
|
|
*/
|
|
|
header: {
|
|
|
type: Array,
|
|
|
- default: Array
|
|
|
+ default: Array,
|
|
|
},
|
|
|
// 是否显示复选框
|
|
|
selection: {
|
|
|
type: Boolean,
|
|
|
- defaut: false
|
|
|
+ defaut: false,
|
|
|
},
|
|
|
// 是否显示每行之间的分隔线
|
|
|
showLine: {
|
|
|
type: Boolean,
|
|
|
- default: false
|
|
|
- }
|
|
|
+ default: false,
|
|
|
+ },
|
|
|
},
|
|
|
- data () {
|
|
|
+ data() {
|
|
|
return {
|
|
|
hasScrollBar: false,
|
|
|
selectedIdList: [],
|
|
|
- }
|
|
|
+ };
|
|
|
},
|
|
|
computed: {
|
|
|
isAllSelected() {
|
|
|
if (this.data && this.data.length > 0) {
|
|
|
- return this.data.length === this.selectedIdList.length
|
|
|
+ return this.data.length === this.selectedIdList.length;
|
|
|
} else {
|
|
|
- return false
|
|
|
+ return false;
|
|
|
}
|
|
|
},
|
|
|
},
|
|
|
watch: {
|
|
|
data: {
|
|
|
handler(v) {
|
|
|
- const newSelectedIdList = []
|
|
|
+ const newSelectedIdList = [];
|
|
|
for (const selectedId of this.selectedIdList) {
|
|
|
- if (this.data.some((item) => {
|
|
|
- return item.id === selectedId
|
|
|
- })) {
|
|
|
- newSelectedIdList.push(selectedId)
|
|
|
+ if (
|
|
|
+ this.data.some((item) => {
|
|
|
+ return item.id === selectedId;
|
|
|
+ })
|
|
|
+ ) {
|
|
|
+ newSelectedIdList.push(selectedId);
|
|
|
}
|
|
|
}
|
|
|
- this.selectedIdList = newSelectedIdList
|
|
|
+ this.selectedIdList = newSelectedIdList;
|
|
|
},
|
|
|
deep: true,
|
|
|
- }
|
|
|
+ },
|
|
|
},
|
|
|
methods: {
|
|
|
onClickSelectAll() {
|
|
|
if (this.isAllSelected) {
|
|
|
- this.selectedIdList = []
|
|
|
+ this.selectedIdList = [];
|
|
|
} else {
|
|
|
- this.selectedIdList = []
|
|
|
- this.data.forEach(item => {
|
|
|
- this.selectedIdList.push(item.id)
|
|
|
- })
|
|
|
+ this.selectedIdList = [];
|
|
|
+ this.data.forEach((item) => {
|
|
|
+ this.selectedIdList.push(item.id);
|
|
|
+ });
|
|
|
}
|
|
|
- this.emitSelectionChange()
|
|
|
+ this.emitSelectionChange();
|
|
|
},
|
|
|
requestMoreData() {
|
|
|
- this.$emit('request-more-data')
|
|
|
+ this.$emit("request-more-data");
|
|
|
},
|
|
|
- emitSelectionChange () {
|
|
|
- let arr = this.data.filter(item => {
|
|
|
+ emitSelectionChange() {
|
|
|
+ let arr = this.data.filter((item) => {
|
|
|
return this.selectedIdList.some((selectedId) => {
|
|
|
- return selectedId === item.id
|
|
|
- })
|
|
|
- })
|
|
|
- this.$emit('selection-change', arr)
|
|
|
+ return selectedId === item.id;
|
|
|
+ });
|
|
|
+ });
|
|
|
+ this.$emit("selection-change", arr);
|
|
|
},
|
|
|
- selectItem (selectedItem, i) {
|
|
|
+ selectItem(selectedItem, i) {
|
|
|
const idx = this.selectedIdList.findIndex((alreadySelectedId) => {
|
|
|
- return alreadySelectedId === selectedItem.id
|
|
|
- })
|
|
|
+ return alreadySelectedId === selectedItem.id;
|
|
|
+ });
|
|
|
if (idx > -1) {
|
|
|
- this.selectedIdList.splice(idx, 1)
|
|
|
+ this.selectedIdList.splice(idx, 1);
|
|
|
} else {
|
|
|
- this.selectedIdList.push(selectedItem.id)
|
|
|
+ this.selectedIdList.push(selectedItem.id);
|
|
|
}
|
|
|
- this.emitSelectionChange()
|
|
|
- }
|
|
|
+ this.emitSelectionChange();
|
|
|
+ },
|
|
|
+ handleTableContentHeight() {
|
|
|
+ const tableContainer = document.querySelector(".panorama");
|
|
|
+ let height = tableContainer.offsetHeight;
|
|
|
+ const offset = 199 + 50;
|
|
|
+ const lastHeight = height - offset;
|
|
|
+ console.log("lastHeight", lastHeight );
|
|
|
+ if (lastHeight > 0) {
|
|
|
+ console.log("table-content", lastHeight);
|
|
|
+ // console.log(this.$refs["t-con"].style);
|
|
|
+ this.$refs["t-con"].style.height = lastHeight + "px";
|
|
|
+ }
|
|
|
+ },
|
|
|
},
|
|
|
- mounted () {
|
|
|
+ mounted() {
|
|
|
const resizeObserver = new ResizeObserver((entries) => {
|
|
|
if (entries[0].target.clientHeight < entries[0].target.scrollHeight) {
|
|
|
- this.hasScrollBar = true
|
|
|
+ this.hasScrollBar = true;
|
|
|
} else {
|
|
|
- this.hasScrollBar = false
|
|
|
+ this.hasScrollBar = false;
|
|
|
}
|
|
|
-
|
|
|
- })
|
|
|
- resizeObserver.observe(this.$refs['t-con'])
|
|
|
+ });
|
|
|
+ resizeObserver.observe(this.$refs["t-con"]);
|
|
|
+ this.handleTableContentHeight();
|
|
|
+ window.addEventListener("resize", this.handleTableContentHeight, false);
|
|
|
},
|
|
|
-}
|
|
|
+ beforeDestroy() {
|
|
|
+ window.removeEventListener("resize", this.handleTableContentHeight, false);
|
|
|
+ },
|
|
|
+};
|
|
|
</script>
|
|
|
|
|
|
<style lang="less" scoped>
|
|
@@ -205,6 +226,10 @@ export default {
|
|
|
width: 100%;
|
|
|
color: #777;
|
|
|
font-size: 14px;
|
|
|
+ flex: 1;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ height: 100%;
|
|
|
|
|
|
.checkbox {
|
|
|
display: inline-block;
|
|
@@ -217,7 +242,7 @@ export default {
|
|
|
}
|
|
|
.inactive {
|
|
|
border-radius: 2px;
|
|
|
- border: 1px solid #D5D8DE;
|
|
|
+ border: 1px solid #d5d8de;
|
|
|
}
|
|
|
.checkbox.active {
|
|
|
}
|
|
@@ -227,7 +252,7 @@ export default {
|
|
|
align-items: center;
|
|
|
width: 100%;
|
|
|
padding: 15px 16px 15px 16px;
|
|
|
- background-color: #F5F7FA;
|
|
|
+ background-color: #f5f7fa;
|
|
|
color: #646566;
|
|
|
line-height: 19px;
|
|
|
position: relative; // 为了设置z-index
|
|
@@ -241,9 +266,12 @@ export default {
|
|
|
|
|
|
// 表格内容
|
|
|
.t-con {
|
|
|
- padding-top: 49px; // 为了能上下滚动,overflow的值不能是visible,导致此元素是个BFC,导致绝对定位的tip在第一行无法显示在此元素区域外,只好让此元素具有padding-top以供第一行的tip显示。
|
|
|
- margin-top: -49px;
|
|
|
- height: calc(100vh - 325px); // 必须指定高度,element-ui的无限滚动指令才能生效
|
|
|
+ // padding-top: 49px; // 为了能上下滚动,overflow的值不能是visible,导致此元素是个BFC,导致绝对定位的tip在第一行无法显示在此元素区域外,只好让此元素具有padding-top以供第一行的tip显示。
|
|
|
+ // margin-top: -49px;
|
|
|
+ // height: calc(100vw - 325px); // 必须指定高度,element-ui的无限滚动指令才能生效
|
|
|
+ height: 200px; // 必须指定高度,element-ui的无限滚动指令才能生效
|
|
|
+ // height: 100%;
|
|
|
+ // flex: 1;
|
|
|
overflow: auto;
|
|
|
.t-item {
|
|
|
display: flex;
|
|
@@ -254,19 +282,19 @@ export default {
|
|
|
visibility: hidden;
|
|
|
}
|
|
|
&:hover {
|
|
|
- background: #F7F7F7;
|
|
|
+ background: #f7f7f7;
|
|
|
.showWhenHover {
|
|
|
visibility: visible;
|
|
|
}
|
|
|
&[active-txt] {
|
|
|
// 关键列,会加粗显示且有hover效果。
|
|
|
- >.themetxt {
|
|
|
+ > .themetxt {
|
|
|
span {
|
|
|
word-break: break-all;
|
|
|
font-weight: bold;
|
|
|
|
|
|
&:hover {
|
|
|
- color: #1FE4DC !important;
|
|
|
+ color: #1fe4dc !important;
|
|
|
cursor: pointer;
|
|
|
}
|
|
|
}
|