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>
相关推荐
黑金IT6 小时前
Python3 + Qt5:实现AJAX异步更新UI
qt·ui·ajax
喵叔哟11 小时前
5. 【Vue实战--孢子记账--Web 版开发】-- 主页UI
前端·vue.js·ui
山海青风1 天前
Axure入门教程 -- 第五章:原型优化与调试
ui·交互·axure
浅陌sss3 天前
Unity 粒子特效在UI中使用裁剪效果
ui·unity·游戏引擎
机器视觉小小测试员3 天前
工业相机常用词语解释
运维·ui·自动化·工业相机
PersistJiao4 天前
Couchbase UI: Search
ui·couchbase
时光追逐者4 天前
一组开源、免费、Metro风格的 WPF UI 控件库
ui·开源·c#·.net·wpf·.netcore·微软技术
专注VB编程开发20年4 天前
代替Winform、Win32控件的一些界面框架Electron,QT等
前端·c++·ui·框架·界面
军训猫猫头4 天前
58.界面参数传递给Command C#例子 WPF例子
开发语言·ui·c#·wpf
半城风月-5 天前
Vue 2 + Element UI 实现密码显示、隐藏切换功能
vue.js·ui·elementui