Skip to content

Commit 1b02e1a

Browse files
committed
fix: avatar list
1 parent f729bbf commit 1b02e1a

File tree

6 files changed

+190
-29
lines changed

6 files changed

+190
-29
lines changed

src/components/AvatarList/Item.vue

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,9 @@
11
<template>
2-
<li :class="[prefixCls, size]">
3-
<slot>
4-
<tooltip>
5-
<template slot="title">{{ tips }}</template>
6-
<avatar :size="size !== 'mini' && size || 20" :src="src" />
7-
</tooltip>
8-
</slot>
9-
</li>
2+
<tooltip v-if="tips !== ''">
3+
<template slot="title">{{ tips }}</template>
4+
<avatar :size="avatarSize" :src="src" />
5+
</tooltip>
6+
<avatar v-else :size="avatarSize" :src="src" />
107
</template>
118

129
<script>
@@ -20,10 +17,6 @@
2017
Tooltip
2118
},
2219
props: {
23-
prefixCls: {
24-
type: String,
25-
default: 'ant-pro-avatar-list-item'
26-
},
2720
tips: {
2821
type: String,
2922
default: '',
@@ -39,6 +32,11 @@
3932
size: this.$parent.size
4033
}
4134
},
35+
computed: {
36+
avatarSize () {
37+
return this.size !== 'mini' && this.size || 20
38+
}
39+
},
4240
watch: {
4341
'$parent.size' (val) {
4442
this.size = val

src/components/AvatarList/List.vue

Lines changed: 37 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,25 @@
1+
<!--
12
<template>
23
<div :class="[prefixCls]">
34
<ul>
45
<slot></slot>
5-
<template v-if="maxLength > 0 && slotsSize > maxLength">
6+
<template v-for="item in filterEmpty($slots.default).slice(0, 3)"></template>
7+
8+
9+
<template v-if="maxLength > 0 && filterEmpty($slots.default).length > maxLength">
610
<avatar-item :size="size">
711
<avatar :size="size !== 'mini' && size || 20" :style="excessItemsStyle">{{ `+${maxLength}` }}</avatar>
812
</avatar-item>
913
</template>
1014
</ul>
1115
</div>
1216
</template>
17+
-->
1318

1419
<script>
1520
import Avatar from 'ant-design-vue/es/avatar'
1621
import AvatarItem from './Item'
22+
import { filterEmpty } from '@/components/_util/util'
1723
1824
export default {
1925
AvatarItem,
@@ -56,24 +62,39 @@
5662
}
5763
},
5864
data () {
59-
return {
60-
slotsSize: 0
61-
}
62-
},
63-
created () {
64-
this.slotsSize = this.$slots.default.length
65-
this.splitSlots()
65+
return {}
6666
},
6767
methods: {
68-
splitSlots () {
69-
if (this.maxLength !== 0 && this.slotsSize > this.maxLength) {
70-
this.$slots.default = this.$slots.default.slice(0, this.maxLength)
68+
getItems(items) {
69+
const classString = {
70+
[`${this.prefixCls}-item`]: true,
71+
[`${this.size}`]: true
72+
}
73+
74+
if (this.maxLength > 0) {
75+
items = items.slice(0, this.maxLength)
76+
items.push((<Avatar size={ this.size } style={ this.excessItemsStyle }>{`+${this.maxLength}`}</Avatar>))
7177
}
78+
const itemList = items.map((item) => (
79+
<li class={ classString }>{ item }</li>
80+
))
81+
return itemList
7282
}
83+
},
84+
render () {
85+
const { prefixCls, size } = this.$props
86+
const classString = {
87+
[`${prefixCls}`]: true,
88+
[`${size}`]: true,
89+
}
90+
const items = filterEmpty(this.$slots.default)
91+
const itemsDom = items && items.length ? <ul class={`${prefixCls}-items`}>{ this.getItems(items) }</ul> : null
92+
93+
return (
94+
<div class={ classString }>
95+
{ itemsDom }
96+
</div>
97+
)
7398
}
7499
}
75-
</script>
76-
77-
<style lang="less" scoped>
78-
79-
</style>
100+
</script>
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
<template>
2+
<span>
3+
{{ lastTime | format }}
4+
</span>
5+
</template>
6+
7+
<script>
8+
9+
function fixedZero(val) {
10+
return val * 1 < 10 ? `0${val}` : val;
11+
}
12+
13+
export default {
14+
name: "CountDown",
15+
props: {
16+
format: {
17+
type: Function,
18+
default: undefined
19+
},
20+
target: {
21+
type: [Date, Number],
22+
required: true,
23+
},
24+
onEnd: {
25+
type: Function,
26+
default: () => {
27+
}
28+
}
29+
},
30+
data() {
31+
return {
32+
dateTime: '0',
33+
originTargetTime: 0,
34+
lastTime: 0,
35+
timer: 0,
36+
interval: 1000
37+
}
38+
},
39+
filters: {
40+
format(time) {
41+
const hours = 60 * 60 * 1000;
42+
const minutes = 60 * 1000;
43+
44+
const h = Math.floor(time / hours);
45+
const m = Math.floor((time - h * hours) / minutes);
46+
const s = Math.floor((time - h * hours - m * minutes) / 1000);
47+
return `${fixedZero(h)}:${fixedZero(m)}:${fixedZero(s)}`
48+
}
49+
},
50+
created() {
51+
this.initTime()
52+
this.tick()
53+
},
54+
methods: {
55+
initTime() {
56+
let lastTime = 0;
57+
let targetTime = 0;
58+
this.originTargetTime = this.target
59+
try {
60+
if (Object.prototype.toString.call(this.target) === '[object Date]') {
61+
targetTime = this.target
62+
} else {
63+
targetTime = new Date(this.target).getTime()
64+
}
65+
} catch (e) {
66+
throw new Error('invalid target prop')
67+
}
68+
69+
lastTime = targetTime - new Date().getTime();
70+
71+
this.lastTime = lastTime < 0 ? 0 : lastTime
72+
},
73+
tick() {
74+
const {onEnd} = this
75+
76+
this.timer = setTimeout(() => {
77+
if (this.lastTime < this.interval) {
78+
clearTimeout(this.timer)
79+
this.lastTime = 0
80+
if (typeof onEnd === 'function') {
81+
onEnd();
82+
}
83+
} else {
84+
this.lastTime -= this.interval
85+
this.tick()
86+
}
87+
}, this.interval)
88+
}
89+
},
90+
beforeUpdate () {
91+
if (this.originTargetTime !== this.target) {
92+
this.initTime()
93+
}
94+
},
95+
beforeDestroy() {
96+
clearTimeout(this.timer)
97+
}
98+
}
99+
</script>
100+
101+
<style scoped>
102+
103+
</style>

src/components/CountDown/index.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import CountDown from './CountDown'
2+
3+
export default CountDown

src/components/_util/util.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/**
2+
* components util
3+
*/
4+
5+
/**
6+
* 清理空值,对象
7+
* @param children
8+
* @returns {*[]}
9+
*/
10+
export function filterEmpty (children = []) {
11+
return children.filter(c => c.tag || (c.text && c.text.trim() !== ''))
12+
}

src/views/Home.vue

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
<avatar-list-item tips="Niko" src="https://gw.alipayobjects.com/zos/rmsportal/kZzEzemZyKLKFsojXItE.png" />
5555
<avatar-list-item tips="Niko" src="https://gw.alipayobjects.com/zos/rmsportal/kZzEzemZyKLKFsojXItE.png" />
5656
<avatar-list-item tips="Niko" src="https://gw.alipayobjects.com/zos/rmsportal/kZzEzemZyKLKFsojXItE.png" />
57+
5758
</avatar-list>
5859

5960
<a-divider type="vertical" style="margin: 0 16px" />
@@ -64,6 +65,16 @@
6465
<avatar-list-item tips="Niko" src="https://gw.alipayobjects.com/zos/rmsportal/kZzEzemZyKLKFsojXItE.png" />
6566
</avatar-list>
6667
</a-card>
68+
69+
<a-divider> CountDown </a-divider>
70+
71+
<a-card>
72+
<count-down
73+
style="font-size: 2rem"
74+
:target="new Date().getTime() + 3000"
75+
:on-end="onEndHandle">
76+
</count-down>
77+
</a-card>
6778
</div>
6879
</template>
6980

@@ -72,15 +83,27 @@
7283
7384
import Trend from '@/components/Trend'
7485
import AvatarList from '@/components/AvatarList'
86+
import CountDown from '@/components/CountDown/CountDown'
7587
7688
const AvatarListItem = AvatarList.AvatarItem
7789
7890
export default {
7991
name: 'Home',
8092
components: {
93+
CountDown,
8194
Trend,
8295
AvatarList,
8396
AvatarListItem
97+
},
98+
data () {
99+
return {
100+
targetTime: new Date().getTime() + 3900000
101+
}
102+
},
103+
methods: {
104+
onEndHandle () {
105+
this.$message.success('CountDown callback!!!')
106+
}
84107
}
85108
}
86109
</script>
@@ -89,10 +112,11 @@
89112
.home {
90113
width: 900px;
91114
margin: 0 auto;
115+
padding: 25px 0;
92116
}
93117
.home > .banner {
94118
text-align: center;
95-
padding-top: 25px;
119+
padding: 25px 0;
96120
margin: 25px 0;
97121
}
98122
</style>

0 commit comments

Comments
 (0)