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 | ... | ... |