<template>
<div class="number-table">
<div class="table">
<span style="width: 12%" v-text="`序号`" />
<span style="width: 66%">
网格名称
<span class="ivu-table-sort">
<i class="ivu-icon ivu-icon-md-arrow-dropup" :class="{ on: sortObj.sortName === 'asc' }" @click="handleSort('sortName', 'asc')" />
<i class="ivu-icon ivu-icon-md-arrow-dropdown" :class="{ on: sortObj.sortName === 'desc' }" @click="handleSort('sortName', 'desc')" />
</span>
</span>
<span style="width: 22%">
诉求数量
<span class="ivu-table-sort">
<i class="ivu-icon ivu-icon-md-arrow-dropup" :class="{ on: sortObj.sortNum === 'asc' }" @click="handleSort('sortNum', 'asc')" />
<i class="ivu-icon ivu-icon-md-arrow-dropdown" :class="{ on: sortObj.sortNum === 'desc' }" @click="handleSort('sortNum', 'desc')" />
</span>
</span>
</div>
<template v-if="tableData.length !== 0 && showScroll">
<div class="broadcast-content-list">
<VueSeamlessScroll
:data="tableData"
ref="seamlessScroll"
:class-option="{
step: 0.5,
waitTime: 5000,
limitMoveNum: 7,
}"
>
<div class="broadcast-content-list-item" v-for="(item, index) in tableData" :key="index">
<ul>
<li
:class="{
oddActive: index % 2 !== 0,
evenActive: index % 2 === 0,
}"
:data="JSON.stringify(item)"
>
<LazyTootip style="width: 38px; color: rgba(254, 215, 2, 1)" :text="index + 1" />
<LazyTootip style="width: 212px; color: rgba(143, 231, 242, 1); font-family: PingFangTC" :text="item.gridName" />
<LazyTootip style="width: 70px; color: rgba(143, 231, 242, 1); font-family: PingFangTC" :text="item.sortNum" />
</li>
</ul>
</div>
</VueSeamlessScroll>
</div>
</template>
<template v-else>
<div class="empty-data">
<p class="empty-data-text">-- 暂无数据 --</p>
</div>
</template>
</div>
</template>
<script>
import VueSeamlessScroll from "vue-seamless-scroll";
import LazyTootip from "./LazyTootip.vue";
import lodash from "lodash";
export default {
components: {
VueSeamlessScroll,
LazyTootip,
},
props: {},
data() {
return {
sortObj: {
sortName: "normal",
sortNum: "normal",
},
tableData: [
{ id: 1, gridName: "1件", sortNum: 1 },
{ id: 2, gridName: "3件", sortNum: 14 },
{ id: 3, gridName: "5件", sortNum: 31 },
{ id: 4, gridName: "6件", sortNum: 67 },
{ id: 5, gridName: "13件", sortNum: 4 },
{ id: 6, gridName: "14件", sortNum: 9 },
{ id: 7, gridName: "2件", sortNum: 10 },
{ id: 8, gridName: "4件", sortNum: 11 },
],
showScroll: true,
};
},
mounted() {
this.$_tableData = lodash.cloneDeep(this.tableData);
},
methods: {
handleSort(name, type) {
Object.keys(this.sortObj).forEach((item) => {
if (item !== name) {
this.sortObj[item] = "normal";
}
});
if (this.sortObj[name] === type) {
this.sortObj[name] = "normal";
this.tableData = lodash.cloneDeep(this.$_tableData);
} else {
this.sortObj[name] = type;
this.tableData.sort(function (a, b) {
if (type === "asc") {
return a[name] - b[name];
} else if (type === "desc") {
return b[name] - a[name];
}
});
}
this.showScroll = false;
this.$nextTick(() => {
this.showScroll = true;
});
},
},
};
</script>
<style lang="less" scoped>
.number-table {
width: 300px;
.table {
width: 100%;
color: #ffffff;
text-align: center;
display: flex;
justify-content: space-between;
background-image: linear-gradient(#00356d, #012955, #011f40, #01172f, #011021, #010b16, #00080f);
span {
font-size: 12px;
}
}
.broadcast-content-list {
height: 130px;
overflow: hidden;
.broadcast-content-list-item {
color: #ffffff;
ul {
list-style: none;
padding: 0;
margin: 0;
li {
display: flex;
justify-content: space-between;
text-align: center;
font-size: 12px;
}
.oddActive {
background: linear-gradient(90deg, rgba(0, 85, 181, 0.7) 0%, rgba(0, 43, 91, 0.39) 100%);
}
.evenActive {
background: linear-gradient(
180.09deg,
rgba(0, 85, 181, 0.1) 0%,
rgba(0, 85, 181, 0) 11.78%,
rgba(0, 85, 181, 0) 92.26%,
rgba(0, 85, 181, 0.1) 100%
);
}
}
}
}
.empty-data {
width: 319px;
height: 137px;
color: rgba(143, 231, 242, 1);
font-family: PingFangTC;
position: absolute;
background: linear-gradient(90deg, rgba(0, 85, 181, 0.7) 0%, rgba(0, 43, 91, 0.39) 100%);
.empty-data-text {
position: relative;
top: 42%;
left: 36%;
}
}
}
.ivu-table-sort {
cursor: pointer;
display: inline-block;
height: 12px;
margin-top: -1px;
overflow: hidden;
position: relative;
vertical-align: middle;
width: 14px;
i {
.on {
color: red;
}
}
}
</style>
LazyTootip.vue 文字超出显示。。。悬浮展示全部。
<template>
<div ref="container" class="truncate">
<Tooltip
v-if="showTooltip"
class="inline-block w-full truncate"
v-bind="$attrs"
transfer
:content="text"
>
<span>{{ text }}</span>
</Tooltip>
<span v-else>{{ text }}</span>
</div>
</template>
<script>
function hasHorizontalScrollbar(element) {
return element.scrollWidth > element.clientWidth;
}
function hasEllipsis(element) {
const temp = element.cloneNode(true);
temp.style.overflow = "auto";
const parentNode = element.parentNode;
// It must be loaded to the parent element, not document.body
parentNode.appendChild(temp);
const hasEllipsis = hasHorizontalScrollbar(temp);
parentNode.removeChild(temp);
return hasEllipsis;
}
export default {
name: "NLazyTooltip",
inheritAttrs: false,
props: {
text: {
type: [String, Number],
require: true
}
},
data() {
return {
showTooltip: false
};
},
watch: {
async text() {
await this.$nextTick();
this.showTooltip = hasEllipsis(this.$refs.container);
}
},
mounted() {
this.showTooltip = hasEllipsis(this.$refs.container);
// console.log(this.showTooltip);
}
};
</script>
<style scoped>
.ivu-tooltip.truncate >>> .ivu-tooltip-rel {
overflow: hidden;
-o-text-overflow: ellipsis;
text-overflow: ellipsis;
white-space: nowrap;
}
/* .truncate {
overflow: hidden;
-o-text-overflow: ellipsis;
text-overflow: ellipsis;
white-space: nowrap;
} */
.inline-block {
display: inline-block;
}
.w-full {
width: 100%;
}
</style>