perf: 优化仪表盘使用sticky方式

This commit is contained in:
kuaifan 2022-03-05 10:59:18 +08:00
parent 8e0a684a9a
commit e969b5b7e4
2 changed files with 248 additions and 189 deletions

View File

@ -5,33 +5,38 @@
<div class="dashboard-hello">{{$L('欢迎您,' + userInfo.nickname)}}</div> <div class="dashboard-hello">{{$L('欢迎您,' + userInfo.nickname)}}</div>
<div class="dashboard-desc">{{$L('以下是你当前的任务统计数据')}}</div> <div class="dashboard-desc">{{$L('以下是你当前的任务统计数据')}}</div>
<ul class="dashboard-block"> <ul class="dashboard-block">
<li @click="dashboard='today'"> <li @click="scrollTo('today')">
<div class="block-title">{{$L('今日待完成')}}</div> <div class="block-title">{{getTitle('today')}}</div>
<div class="block-data"> <div class="block-data">
<div class="block-num">{{dashboardTask.today.length}}</div> <div class="block-num">{{dashboardTask.today.length}}</div>
<i class="taskfont">&#xe6f4;</i> <i class="taskfont">&#xe6f4;</i>
</div> </div>
</li> </li>
<li @click="dashboard='overdue'"> <li @click="scrollTo('overdue')">
<div class="block-title">{{$L('超期未完成')}}</div> <div class="block-title">{{getTitle('overdue')}}</div>
<div class="block-data"> <div class="block-data">
<div class="block-num">{{dashboardTask.overdue.length}}</div> <div class="block-num">{{dashboardTask.overdue.length}}</div>
<i class="taskfont">&#xe603;</i> <i class="taskfont">&#xe603;</i>
</div> </div>
</li> </li>
<li @click="dashboard='all'"> <li @click="scrollTo('all')">
<div class="block-title">{{$L('待完成任务')}}</div> <div class="block-title">{{getTitle('all')}}</div>
<div class="block-data"> <div class="block-data">
<div class="block-num">{{dashboardTask.all.length}}</div> <div class="block-num">{{dashboardTask.all.length}}</div>
<i class="taskfont">&#xe6f9;</i> <i class="taskfont">&#xe6f9;</i>
</div> </div>
</li> </li>
</ul> </ul>
<template v-if="list.length > 0"> <div class="dashboard-list overlay-y">
<div class="dashboard-title">{{title}}</div> <div
<ul class="dashboard-list overlay-y"> :ref="`type_${column.type}`"
v-for="(column, index) in columns"
v-if="column.list.length > 0"
:key="index">
<div class="dashboard-title">{{column.title}}</div>
<ul class="dashboard-li">
<li <li
v-for="(item, index) in list" v-for="(item, index) in column.list"
:key="index" :key="index"
:class="{complete: item.complete_at}" :class="{complete: item.complete_at}"
:style="item.color ? {backgroundColor: item.color} : {}" :style="item.color ? {backgroundColor: item.color} : {}"
@ -70,7 +75,8 @@
</ETooltip> </ETooltip>
</li> </li>
</ul> </ul>
</template> </div>
</div>
</div> </div>
</div> </div>
</template> </template>
@ -110,13 +116,34 @@ export default {
}, },
computed: { computed: {
...mapState(['userInfo', 'cacheProjects', 'taskId']), ...mapState(['userInfo']),
...mapGetters(['dashboardTask', 'transforTasks']), ...mapGetters(['dashboardTask', 'transforTasks']),
title() { columns() {
const {dashboard} = this; let list = [];
switch (dashboard) { ['today', 'overdue', 'all'].some(type => {
let data = this.transforTasks(this.dashboardTask[type]);
list.push({
type,
title: this.getTitle(type),
list: data.sort((a, b) => {
return $A.Date(a.end_at || "2099-12-31 23:59:59") - $A.Date(b.end_at || "2099-12-31 23:59:59");
})
})
})
return list;
},
total() {
const {dashboardTask} = this;
return dashboardTask.today.length + dashboardTask.overdue.length + dashboardTask.all.length;
},
},
methods: {
getTitle(type) {
switch (type) {
case 'today': case 'today':
return this.$L('今日任务'); return this.$L('今日任务');
case 'overdue': case 'overdue':
@ -128,27 +155,20 @@ export default {
} }
}, },
list() { scrollTo(type) {
const {dashboard} = this; try {
let data = []; this.$refs[`type_${type}`][0].scrollIntoView({
switch (dashboard) { behavior: 'instant',
case 'today': inline: 'end',
data = this.transforTasks(this.dashboardTask.today);
break
case 'overdue':
data = this.transforTasks(this.dashboardTask.overdue);
break
case 'all':
data = this.transforTasks(this.dashboardTask.all);
break
}
return data.sort((a, b) => {
return $A.Date(a.end_at || "2099-12-31 23:59:59") - $A.Date(b.end_at || "2099-12-31 23:59:59");
}); });
}, } catch (e) {
scrollIntoView(this.$refs[`type_${type}`][0], {
behavior: 'instant',
inline: 'end',
})
}
}, },
methods: {
openTask(task) { openTask(task) {
this.$store.dispatch("openTask", task) this.$store.dispatch("openTask", task)
}, },

View File

@ -5,13 +5,22 @@
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
background-color: #ffffff;
.dashboard-wrapper { .dashboard-wrapper {
width: 664px; width: 100%;
max-width: 80%;
max-height: 80%; max-height: 80%;
margin-bottom: 2%;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center;
.dashboard-hello,
.dashboard-desc ,
.dashboard-block ,
.dashboard-list .dashboard-title,
.dashboard-list .dashboard-li {
width: 660px;
max-width: 80%;
margin: 0 auto;
}
.dashboard-hello { .dashboard-hello {
padding: 0 12px; padding: 0 12px;
color: #333333; color: #333333;
@ -41,10 +50,7 @@
flex-direction: column; flex-direction: column;
justify-content: center; justify-content: center;
cursor: pointer; cursor: pointer;
transition: box-shadow 0.3s; transition: transform 0.5s ease-out 0s, box-shadow 0.3s ease-out 0s;
&:hover {
box-shadow: 0 0 10px #cccccc;
}
&:first-child { &:first-child {
background-color: #6f9ef6; background-color: #6f9ef6;
} }
@ -52,6 +58,16 @@
background-color: #98de6e; background-color: #98de6e;
margin-right: 0; margin-right: 0;
} }
&:hover {
transform: translateY(-3px);
box-shadow: 0 2px 10px 0 #fa8e8c;
&:first-child {
box-shadow: 0 2px 10px 0 #6f9ef6;
}
&:last-child {
box-shadow: 0 2px 10px 0 #98de6e;
}
}
.block-title { .block-title {
color: rgba(255, 255, 255, 0.6); color: rgba(255, 255, 255, 0.6);
font-size: 12px; font-size: 12px;
@ -74,31 +90,46 @@
} }
} }
} }
.dashboard-list {
width: 100%;
margin-top: 48px;
overflow: auto;
.dashboard-title { .dashboard-title {
margin-top: 60px; position: sticky;
top: 0;
z-index: 1;
margin: 0 auto;
padding: 0 12px; padding: 0 12px;
height: 46px;
line-height: 46px;
font-weight: 600; font-weight: 600;
font-size: 15px; font-size: 15px;
background-color: #ffffff;
} }
.dashboard-list { .dashboard-li {
margin-top: 4px; margin: 0 auto;
padding: 0 12px; padding: 0 12px;
overflow: auto; overflow: hidden;
> li { > li {
position: relative; position: relative;
list-style: none; list-style: none;
display: flex; display: flex;
background: #F9FAFB; background: #F9FAFB;
margin-top: 12px; padding: 12px;
padding: 8px 12px;
border-radius: 6px;
cursor: pointer; cursor: pointer;
transition: box-shadow 0.3s; transition: box-shadow 0.3s,transform 0.2s;
border-bottom: 1px solid #f1f2f4;
&:hover { &:hover {
box-shadow: 0 0 6px #dfdfdf; transform: translateX(-2px);
}
&:first-child {
border-top-right-radius: 6px;
border-top-left-radius: 6px;
} }
&:last-child { &:last-child {
margin-bottom: 12px; border-bottom-right-radius: 6px;
border-bottom-left-radius: 6px;
border-bottom: 0;
} }
&.complete { &.complete {
.item-title { .item-title {
@ -187,6 +218,7 @@
} }
} }
} }
}
.nopage { .nopage {
width: 100%; width: 100%;
height: 100%; height: 100%;
@ -217,8 +249,14 @@
.page-dashboard { .page-dashboard {
.dashboard-wrapper { .dashboard-wrapper {
display: block; display: block;
max-width: 86%;
max-height: 86%; max-height: 86%;
.dashboard-hello,
.dashboard-desc ,
.dashboard-block ,
.dashboard-list .dashboard-title,
.dashboard-list .dashboard-li {
max-width: 86%;
}
.dashboard-block { .dashboard-block {
display: block; display: block;
margin-top: 10px; margin-top: 10px;
@ -227,11 +265,11 @@
padding: 8px 12px; padding: 8px 12px;
} }
} }
.dashboard-title {
margin-top: 36px;
}
.dashboard-list { .dashboard-list {
padding-bottom: 22px; overflow: visible !important;
padding-bottom: 2px;
> ul {
margin-bottom: 36px;
> li { > li {
.item-title { .item-title {
overflow: hidden; overflow: hidden;
@ -243,3 +281,4 @@
} }
} }
} }
}