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,9 +14,13 @@ | ||
14 | <Avatar src="https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png" shape="square"></Avatar> | 14 | <Avatar src="https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png" shape="square"></Avatar> |
15 | <Avatar src="https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png" size="small" shape="square"></Avatar> | 15 | <Avatar src="https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png" size="small" shape="square"></Avatar> |
16 | <br><br> | 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 | <br><br> | 24 | <br><br> |
21 | <Badge dot> | 25 | <Badge dot> |
22 | <Avatar icon="person" shape="square"></Avatar> | 26 | <Avatar icon="person" shape="square"></Avatar> |
@@ -24,10 +28,20 @@ | @@ -24,10 +28,20 @@ | ||
24 | <Badge :count="3"> | 28 | <Badge :count="3"> |
25 | <Avatar icon="person" shape="square"></Avatar> | 29 | <Avatar icon="person" shape="square"></Avatar> |
26 | </Badge> | 30 | </Badge> |
31 | + <Button @click="change">change</Button> | ||
27 | </div> | 32 | </div> |
28 | </template> | 33 | </template> |
29 | <script> | 34 | <script> |
30 | export default { | 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 | </script> | 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 | <script> | 8 | <script> |
2 | import Icon from '../icon'; | 9 | import Icon from '../icon'; |
3 | import { oneOf } from '../../utils/assist'; | 10 | import { oneOf } from '../../utils/assist'; |
@@ -6,6 +13,7 @@ | @@ -6,6 +13,7 @@ | ||
6 | 13 | ||
7 | export default { | 14 | export default { |
8 | name: 'Avatar', | 15 | name: 'Avatar', |
16 | + components: { Icon }, | ||
9 | props: { | 17 | props: { |
10 | shape: { | 18 | shape: { |
11 | validator (value) { | 19 | validator (value) { |
@@ -26,6 +34,13 @@ | @@ -26,6 +34,13 @@ | ||
26 | type: String | 34 | type: String |
27 | } | 35 | } |
28 | }, | 36 | }, |
37 | + data () { | ||
38 | + return { | ||
39 | + prefixCls: prefixCls, | ||
40 | + scale: 1, | ||
41 | + isSlotShow: false | ||
42 | + }; | ||
43 | + }, | ||
29 | computed: { | 44 | computed: { |
30 | classes () { | 45 | classes () { |
31 | return [ | 46 | return [ |
@@ -37,32 +52,42 @@ | @@ -37,32 +52,42 @@ | ||
37 | [`${prefixCls}-icon`]: !!this.icon | 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 | </script> | 93 | </script> |
69 | \ No newline at end of file | 94 | \ No newline at end of file |