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 |