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>
相关推荐
芋芋qwq3 小时前
Unity UI射线检测 道具拖拽
ui·unity·游戏引擎
赢乐3 小时前
使用Element UI实现前端分页,前端搜索,及el-table表格跨页选择数据,切换分页保留分页数据,限制多选数量
前端分页·element ui·跨页选择·el-table表格·限制多选数量·切换分页保留数据·前端搜索过滤
鸿蒙自习室4 小时前
鸿蒙多线程开发——线程间数据通信对象02
ui·harmonyos·鸿蒙
大霞上仙7 小时前
element ui table 每行不同状态
vue.js·ui·elementui
栈老师不回家15 小时前
Element UI 组件库详解【Vue】
前端·vue.js·ui
郭梧悠17 小时前
HarmonyOS(57) UI性能优化
ui·性能优化·harmonyos
wyh要好好学习1 天前
WPF数据加载时添加进度条
ui·wpf
code_shenbing1 天前
跨平台WPF框架Avalonia教程 三
前端·microsoft·ui·c#·wpf·跨平台·界面设计
vvw&2 天前
如何使用 Docker Compose 安装 WireGuard UI
linux·服务器·ui·docker·容器·wireguard·异地组网
老码沉思录2 天前
Android开发实战班 - 现代 UI 开发之 Material Design及自定义主题
android·ui