element ui el-avatar 源码解析零基础逐行解析

avatar功能介绍

快捷配置头像的样式

avatar 的参数配置

属性 说明 参数
size 尺寸 type string 类型 ('large','medium','small')number类型 validator 校验
shape 形状 circle (原型) square(方形)
icon 传入的icon
src 传入的图片 string类型 可以是本地图片(本地图片需要在js中requir导入,不可直接使用相对路劲引用) 也可以是网络地址
srcSet 是一种响应式网页设计,它允许开发者为图像提供不同大小和分辨率的版本,以便根据设备的屏幕大小和像素密度自动选择最适合的图像进行显示 例如srcset="image1.jpg 1x, image2.jpg 2x, image3.jpg 3x" 属性接受一组逗号分隔的描述符和图像路径 浏览器会根据设备的像素密度选择合适的图像进行加载,例如在像素密度为2x的设备上,会选择加载 image2.jpg。
error 传入的图片异常函数 图片加载失败时,触发的异常函数
fit object-fit 的参数 img图片自适应方案,类似于background-size的属性 fill 默认,不保证保持原有的比例,内容拉伸填充整个内容容器 contain 保持原有尺寸比例。内容被缩放。 cover 保持原有尺寸比例。但部分内容可能被剪切。 none 保留原有元素内容的长度和宽度,也就是说内容不会被重置。 scale-down 保持原有尺寸比例。内容的尺寸与 none 或 contain 中的一个相同,取决于它们两个之间谁得到的对象尺寸会更小一些。

avatar的样式类名根据传入的参数处理

javascript 复制代码
  computed: {
    avatarClass() {
      // 类名 集合
      const { size, icon, shape } = this;
      console.log("size",size)
      // size avatar 图标的尺寸
      // icon 图标
      // shpe形状
      let classList = ['el-avatar'];
            // classList 类名 集合
      if (size && typeof size === 'string') {
        classList.push(`el-avatar--${size}`);
      }

      if (icon) {
        classList.push('el-avatar--icon');
      }

      if (shape) {
        classList.push(`el-avatar--${shape}`);
      }
      // classList.join(" ") 就是将名的数组以空格为连接符拼接到一起
      return classList.join(' ');
    }
  },

代码逻辑

  • 定义默认的 classList = 为 ['el-avatar']
  • 根据size、icon、shape 和 el-avatar 拼接成类名
  • 然后将拼接好的类名数组用join(' ')拼接成字符串
  • 返回 并渲染到 html的class上

头像异常的处理逻辑

javascript 复制代码
    handleError() {
      const { error } = this;
      const errorFlag = error ? error() : undefined;
      // 图片类头像加载失败的回调, 返回 false 会关闭组件默认的 fallback 行为
      if (errorFlag !== false) {
        this.isImageExist = false;
      }
    }

renderAvatar 渲染头像的主体逻辑

javascript 复制代码
    renderAvatar() {
      const { icon, src, alt, isImageExist, srcSet, fit } = this;
        console.log("=======================",icon, src, alt, isImageExist, srcSet, fit)
      if (isImageExist && src) {
        // 图片路径存在,就渲染图片
        return <img
          src={src}
          onError={this.handleError}
          alt={alt}
          srcSet={srcSet}
          style={{ 'object-fit': fit }}/>
      }
      // src 图片的路径
     // onError 图片异常触发的钩子函数    
     //srcSet   srcset="image1.jpg 1x, image2.jpg 2x, image3.jpg 3x"
     //srcSet 属性接受一组逗号分隔的描述符和图像路径    
     //浏览器会根据设备的像素密度选择合适的图像进行加载,例如在像素密度为2x的设备上,会选择加载 image2.jpg。
      if (icon) {
        //如果icon存在 就渲染 传入的icon
        return (<i class={icon} />);
      }

      return this.$slots.default;//如果没有传入icon url  就渲染组件的默认插槽 如果组件引用标签内没有包裹东西,就是空的
    }

代码细节

  • 返回一个html片段
  • 如果传入的src存在就渲染图片 alt 是图片不显示时 显示的文本
  • 如果icon存在,就渲染icon图标
  • 入宫src和icon都不存在就渲染组件的默认插槽
  • this.$slots.default是组件的默认插槽

render函数里的代码

javascript 复制代码
  render() {
    const { avatarClass, size } = this;//使用解构,获取到avatarClass 和size 
    const sizeStyle = typeof size === 'number' ? {
      height: `${size}px`,
      width: `${size}px`,
      lineHeight: `${size}px`
    } : {};
    //如果传入的 size 是number类型的 就直接拼接px形成style对象
    
    return (
      <span class={ avatarClass } style={ sizeStyle }>
        {
          this.renderAvatar()
        }
      </span>
    );
  }

render函数里的代码逻辑

  • 使用解构赋值 获取到组件里的avatarClass(类名)和size(尺寸)
  • 如果size的类型时 number 则使用模板字符串组装 height ,width,lineHeight组成的sizeStyle对象
  • 将 avatarClass 和 sizeStyle 挂载到span上 使类名和 style生效,这种写法非常不错,逻辑和模板分离
  • 最后调用renderAvatar()函数,使得函数中定义的逻辑模板渲染在html中
  • render函数可以替代template实现模板的渲染,并且效率比直接写template更高

全部代码

javascript 复制代码
<script>
export default {
  name: 'ElAvatar',

  props: {
    size: {
      type: [Number, String],//type 
      validator(val) {
        // validator 可以是一个函数 返回值是 boolean true表示传入有效,false表示传入的数据格式不对,会提示格式不对
        if (typeof val === 'string') {
          return ['large', 'medium', 'small'].includes(val);
        }
        return typeof val === 'number';
      }
    },
    shape: {//形状 circle圆形 square 方形 
      type: String,
      default: 'circle',
      validator(val) {
        return ['circle', 'square'].includes(val);
      }
    },
    icon: String,//传入的图标 icon
    src: String,//传入的路径
    alt: String,//图片不显示时 显示的替代文本
    srcSet: String,//是一种响应式网页设计,它允许开发者为图像提供不同大小和分辨率的版本,以便根据设备的屏幕大小和像素密度自动选择最适合的图像进行显示
    error: Function,//图片加载失败,触发的异常函数
    fit: {
      type: String,
      default: 'contain'
    }
  },
  // object-fit
  // img标签的图片自适应方案
  // fill 默认,不保证保持原有的比例,内容拉伸填充整个内容容器。
  // contain  保持原有尺寸比例。内容被缩放。
  // cover 保持原有尺寸比例。但部分内容可能被剪切。
  // none	 保留原有元素内容的长度和宽度,也就是说内容不会被重置。
// scale-down	保持原有尺寸比例。内容的尺寸与 none 或 contain 中的一个相同,取决于它们两个之间谁得到的对象尺寸会更小一些。
  data() {
    return {
      isImageExist: true
    };
  },

  computed: {
    avatarClass() {
      // 类名 集合
      const { size, icon, shape } = this;
      console.log("size",size)
      // size avatar 图标的尺寸
      // icon 图标
      // shpe形状
      let classList = ['el-avatar'];
            // classList 类名 集合
      if (size && typeof size === 'string') {
        classList.push(`el-avatar--${size}`);
      }

      if (icon) {
        classList.push('el-avatar--icon');
      }

      if (shape) {
        classList.push(`el-avatar--${shape}`);
      }
      // classList.join(" ") 就是将名的数组以空格为连接符拼接到一起
      return classList.join(' ');
    }
  },
  methods: {
    handleError() {
      const { error } = this;
      const errorFlag = error ? error() : undefined;
      // 图片类头像加载失败的回调, 返回 false 会关闭组件默认的 fallback 行为
      if (errorFlag !== false) {
        this.isImageExist = false;
      }
    },
    renderAvatar() {
      const { icon, src, alt, isImageExist, srcSet, fit } = this;
        console.log("=======================",icon, src, alt, isImageExist, srcSet, fit)
      if (isImageExist && src) {

        // 图片路径存在,就渲染图片
        return <img
          src={src}
          onError={this.handleError}
          alt={alt}
          srcSet={srcSet}
          style={{ 'object-fit': fit }}/>
      }
      // src 图片的路径
     // onError 图片异常触发的钩子函数    
     //srcSet   srcset="image1.jpg 1x, image2.jpg 2x, image3.jpg 3x"
     //srcSet 属性接受一组逗号分隔的描述符和图像路径    
     //浏览器会根据设备的像素密度选择合适的图像进行加载,例如在像素密度为2x的设备上,会选择加载 image2.jpg。
      if (icon) {
        //如果icon存在 就渲染 传入的icon
        return (<i class={icon} />);
      }

      return this.$slots.default;//如果没有传入icon url  就渲染组件的默认插槽 如果组件引用标签内没有包裹东西,就是空的
    }
  },

  render() {
    const { avatarClass, size } = this;//使用解构,获取到avatarClass 和size 
    const sizeStyle = typeof size === 'number' ? {
      height: `${size}px`,
      width: `${size}px`,
      lineHeight: `${size}px`
    } : {};
    //如果传入的 size 是number类型的 就直接拼接px形成style对象
    
    return (
      <span class={ avatarClass } style={ sizeStyle }>
        {
          this.renderAvatar()
        }
      </span>
    );
  }

};
</script>
相关推荐
sg_knight21 小时前
设计模式实战:状态模式(State)
python·ui·设计模式·状态模式·state
黄思搏21 小时前
基于标注平台数据的 Unity UI 自动化构建工作流设计与工程实践
ui·unity·蓝湖·vectoui
小樱花的樱花1 天前
1 项目概述
开发语言·c++·qt·ui
2301_822703201 天前
开源鸿蒙跨平台Flutter开发:跨端图形渲染引擎的类型边界与命名空间陷阱:以多维雷达图绘制中的 dart:ui 及 StrokeJoin 异常为例
算法·flutter·ui·开源·图形渲染·harmonyos·鸿蒙
极梦网络无忧1 天前
Windows UI Automation实现抖音直播间监控(桌面端场控助手核心方案)
windows·ui
newbe365241 天前
Design.md:让 AI 一致性进行前端 UI 设计的解决方案
前端·人工智能·ui
猫仍在1 天前
Playwright 架构UI 自动化质量保障平台
ui·架构·自动化
AI_零食2 天前
开源鸿蒙跨平台Flutter开发:昼夜节律与睡眠相位-脑电波周期与最佳苏醒测绘架构
flutter·ui·华为·架构·开源·harmonyos·鸿蒙
stevenzqzq2 天前
推荐页核心 UI 实现逻辑说明
ui
AI_零食2 天前
Flutter 框架跨平台鸿蒙开发 - 自定义式按钮设计应用
学习·flutter·ui·华为·harmonyos·鸿蒙