Commit ad2255781235da85828b221583460d88d1a073e1

Authored by 梁灏
1 parent ececc3bb

add Avatar component

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