I. Component introduction

[website links] (component | Element (gitee. IO))

The Avatar component displays the user’s Avatar in the form of ICONS, pictures, or characters.

1.1 attributes

Common attributes:

  • Size: Sets the size of the profile picture. The value can be “number” or “string”large / medium / small, the default value islarge;
  • Shape: Indicates the shape. This parameter is optionalcircle / square, the default value iscircle;

Icon form:

  • Icon: Use the icon, as with the icon component, pass in the corresponding icon class;

Picture format:

  • SRC: Use the image, passing in the address of the image
  • SrcSet: Using pictures, a comma-separated list of one or more strings indicates a series of possible images used by the user agent
  • Alt: Alternative text for the image, displayed if the image fails to load;
  • Fit: When the display type is picture, set how the picture fits into the container and will be treated as a pictureobject-fitProperty, the default value iscover.

1.2 event

  • Error is a callback to an image that failed to load. Returning false turns off the component’s default fallback behavior

Second, source code analysis

2.1 the template

<template>
  <span :class="avatarClass" :style="sizeStyle">// Image format<img
      v-if="(src || srcSet) && ! hasLoadError"
      :src="src"
      :alt="alt"
      :srcset="srcSet"
      :style="fitStyle"
      @error="handleError"
    >// In the form of an icon<i v-else-if="icon" :class="icon"></i>// In text form<slot v-else></slot>
  </span>
</template>
Copy the code

2.2 the script

<script lang="ts">
export default defineComponent({
  props: {
    size: {
      type: [Number.String] as PropType<number | string>,
      // A custom validation function that will throw a control sleeve warning if the validation fails in a non-production environment
      validator(this: never, val: unknown) {
        if (typeof val === 'string') {
          return ['large'.'medium'.'small'].includes(val)
        }
        return typeof val === 'number'
      },
      default: 'large',},shape: {
      type: String.default: 'circle'.validator(this: never, val: string) {
        return ['circle'.'square'].includes(val)
      },
    },
    icon: String.src: {
      type: String.default: ' ',},alt: String.srcSet: String.fit: {
      type: String.default: 'cover',}},emits: [ERROR_EVENT],
  setup(props, { emit }) {
    const hasLoadError = ref(false)

    const src = toRef(props, 'src')
    
    // Calculate attributes, control class
    const avatarClass = computed(() = > {
      const { size, icon, shape } = props
      const classList = ['el-avatar']
      if (size && typeof size === 'string') {
        classList.push(`el-avatar--${size}`)}if (icon) {
        classList.push('el-avatar--icon')}if (shape) {
        classList.push(`el-avatar--${shape}`)}return classList
    })
    
    // Calculate attributes to control size
    const sizeStyle = computed(() = > {
      const { size } = props
      return typeof size === 'number' ? {
        height: `${size}px`.width: `${size}px`.lineHeight: `${size}px`,} : {}})// Calculate attributes and control fit
    const fitStyle = computed(() = > ({
      objectFit: props.fit,
    }))

    function handleError(e: Event) {
      hasLoadError.value = true
      emit(ERROR_EVENT, e)
    }
    
    // Clear hasLoadError when image SRC changes
    watch(src,() = >{
      hasLoadError.value = false
    })
    
    return {
      hasLoadError, avatarClass, sizeStyle, handleError,
      fitStyle,
    }
  },
})
</script>
Copy the code