Commit ad2255781235da85828b221583460d88d1a073e1
1 parent
ececc3bb
add Avatar component
Showing
2 changed files
with
65 additions
and
26 deletions
Show diff stats
examples/routers/avatar.vue
... | ... | @@ -14,9 +14,13 @@ |
14 | 14 | <Avatar src="https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png" shape="square"></Avatar> |
15 | 15 | <Avatar src="https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png" size="small" shape="square"></Avatar> |
16 | 16 | <br><br> |
17 | - <Avatar>Aresn</Avatar> | |
18 | - <Avatar>U</Avatar> | |
19 | - <Avatar>Tomserm</Avatar> | |
17 | + <Avatar size="large">Leo</Avatar> | |
18 | + <Avatar size="large">A</Avatar> | |
19 | + <Avatar size="default">A</Avatar> | |
20 | + <Avatar size="small">A</Avatar> | |
21 | + <Avatar size="large">Tomserm</Avatar> | |
22 | + <Avatar size="large">{{ name }}</Avatar> | |
23 | + {{ name }} | |
20 | 24 | <br><br> |
21 | 25 | <Badge dot> |
22 | 26 | <Avatar icon="person" shape="square"></Avatar> |
... | ... | @@ -24,10 +28,20 @@ |
24 | 28 | <Badge :count="3"> |
25 | 29 | <Avatar icon="person" shape="square"></Avatar> |
26 | 30 | </Badge> |
31 | + <Button @click="change">change</Button> | |
27 | 32 | </div> |
28 | 33 | </template> |
29 | 34 | <script> |
30 | 35 | export default { |
31 | - | |
36 | + data () { | |
37 | + return { | |
38 | + name: 'Aresn' | |
39 | + } | |
40 | + }, | |
41 | + methods: { | |
42 | + change () { | |
43 | + this.name = 'Tomserm' | |
44 | + } | |
45 | + } | |
32 | 46 | } |
33 | 47 | </script> | ... | ... |
src/components/avatar/avatar.vue
1 | +<template> | |
2 | + <span :class="classes"> | |
3 | + <img :src="src" v-if="src"> | |
4 | + <Icon :type="icon" v-else-if="icon"></Icon> | |
5 | + <span ref="children" :class="[prefixCls + '-string']" :style="childrenStyle" v-else><slot></slot></span> | |
6 | + </span> | |
7 | +</template> | |
1 | 8 | <script> |
2 | 9 | import Icon from '../icon'; |
3 | 10 | import { oneOf } from '../../utils/assist'; |
... | ... | @@ -6,6 +13,7 @@ |
6 | 13 | |
7 | 14 | export default { |
8 | 15 | name: 'Avatar', |
16 | + components: { Icon }, | |
9 | 17 | props: { |
10 | 18 | shape: { |
11 | 19 | validator (value) { |
... | ... | @@ -26,6 +34,13 @@ |
26 | 34 | type: String |
27 | 35 | } |
28 | 36 | }, |
37 | + data () { | |
38 | + return { | |
39 | + prefixCls: prefixCls, | |
40 | + scale: 1, | |
41 | + isSlotShow: false | |
42 | + }; | |
43 | + }, | |
29 | 44 | computed: { |
30 | 45 | classes () { |
31 | 46 | return [ |
... | ... | @@ -37,32 +52,42 @@ |
37 | 52 | [`${prefixCls}-icon`]: !!this.icon |
38 | 53 | } |
39 | 54 | ]; |
55 | + }, | |
56 | + childrenStyle () { | |
57 | + let style = {}; | |
58 | + if (this.isSlotShow) { | |
59 | + style = { | |
60 | + msTransform: `scale(${this.scale})`, | |
61 | + WebkitTransform: `scale(${this.scale})`, | |
62 | + transform: `scale(${this.scale})`, | |
63 | + position: 'absolute', | |
64 | + display: 'inline-block', | |
65 | + left: `calc(50% - ${Math.round(this.$refs.children.offsetWidth / 2)}px)` | |
66 | + }; | |
67 | + } | |
68 | + return style; | |
40 | 69 | } |
41 | 70 | }, |
42 | - render (h) { | |
43 | - let innerNode = ''; | |
44 | - | |
45 | - if (this.src) { | |
46 | - innerNode = h('img', { | |
47 | - attrs: { | |
48 | - src: this.src | |
49 | - } | |
50 | - }); | |
51 | - } else if (this.icon) { | |
52 | - innerNode = h(Icon, { | |
53 | - props: { | |
54 | - type: this.icon | |
71 | + methods: { | |
72 | + setScale () { | |
73 | + this.isSlotShow = !this.src && !this.icon; | |
74 | + if (this.$slots.default) { | |
75 | + const childrenWidth = this.$refs.children.offsetWidth; | |
76 | + const avatarWidth = this.$el.getBoundingClientRect().width; | |
77 | + // add 4px gap for each side to get better performance | |
78 | + if (avatarWidth - 8 < childrenWidth) { | |
79 | + this.scale = (avatarWidth - 8) / childrenWidth; | |
80 | + } else { | |
81 | + this.scale = 1; | |
55 | 82 | } |
56 | - }); | |
57 | - } else if (this.$slots.default) { | |
58 | - innerNode = h('span', { | |
59 | - 'class': `${prefixCls}-string` | |
60 | - }, this.$slots.default); | |
83 | + } | |
61 | 84 | } |
62 | - | |
63 | - return h('span', { | |
64 | - 'class': this.classes | |
65 | - }, [innerNode]); | |
85 | + }, | |
86 | + mounted () { | |
87 | + this.setScale(); | |
88 | + }, | |
89 | + updated () { | |
90 | + this.setScale(); | |
66 | 91 | } |
67 | 92 | }; |
68 | 93 | </script> |
69 | 94 | \ No newline at end of file | ... | ... |