简介

时间轴组件Timeline 罕用于垂直展现的工夫流信息。 当有一系列信息需按工夫排列时,应用时间轴进行视觉上的(正序或倒序)串联。本文将剖析其源码实现,急躁读完,置信会对您有所帮忙。 组件文档 Timeline gitee源码

更多组件分析详见 Element 2 源码分析组件总览

组件源码

时间轴性能提供了两个组件:el-timelineel-timeline-item

各组件的 prop 申明,各属性性能阐明详见官网文档 Timeline#attributes 。

根组件 main.vue

根组件是一个函数式组件,应用渲染函数/JSX 语法一个无序列表<ul> 元素。提供匿名插槽展现节点内容。

// packages\timeline\src\main.vue<script>  export default {    name: 'ElTimeline',    props: {      reverse: {        type: Boolean,        default: false      }    },    // dead code    provide() {      return {        timeline: this      };    },    // 渲染函数    render() {      const reverse = this.reverse;      const classes = {        'el-timeline': true,        'is-reverse': reverse      };      let slots = this.$slots.default || [];      if (reverse) {        slots = slots.reverse();      }      return (<ul class={ classes }>        { slots }      </ul>);    }  };</script> 

属性 reverse 用于节点排序方向。通过this.$slots拜访传入插槽的 元素类型为vnode节点数组,而后应用 办法reverse()将数组中元素的地位颠倒。

let slots = this.$slots.default || [];if (reverse) {   slots = slots.reverse();}
此排序是元素节点地位程序,不是节点内工夫戳排序。

代码中存在不少 dead code,具体性能意义不明(感觉性能开发一半就停了)。

属性 reverse值为 ture,节点逆序时生成类名is-reverse,然而样式表中未定义此类。

const classes = {  'is-reverse': reverse};// packages\theme-chalk\src\timeline.scss@include b(timeline) {  margin: 0;  font-size: $--font-size-base;  list-style: none;  // 暗藏末节点轴线  & .el-timeline-item:last-child {    & .el-timeline-item__tail {      display: none;    }  }}

依赖注入代码即便正文掉也不影响组件性能。

// packages\timeline\src\main.vue provide() {  return {    timeline: this  };},// packages\timeline\src\item.vueinject: ['timeline'],

节点组件 item.vue

节点组件的模板用于渲染一个示意列表里的条目标<li> 元素。该元素节点下内容蕴含三局部:

  • 垂直方向轴线。
  • 节点/图标。
  • 内容(含工夫戳)。
<template>  <li class="el-timeline-item">    <!-- 轴线 -->    <div class="el-timeline-item__tail"></div>    <!-- 节点/图标 -->    <div v-if="!$slots.dot" class="el-timeline-item__node" >      // 图标    </div>    <div v-if="$slots.dot" class="el-timeline-item__dot">      <slot name="dot"></slot>    </div>    <!-- 信息内容 -->    <div class="el-timeline-item__wrapper">      // 内容    </div>  </li></template>  

渲染成果如下:

上一大节中介绍了根组件定义了款式用于设置末节点元素的轴线不显示。

.el-timeline .el-timeline-item:last-child .el-timeline-item__tail {  display: none;}

轴线

类名el-timeline-item__tail的div元素应用相对布局,在节点元素外部居左left: 4px,并通过定义border-left height款式属性来实现垂直轴线成果。

.el-timeline-item__tail {  position: absolute;  left: 4px;  height: 100%;  border-left: 2px solid #e4e7ed;}

节点

时间轴节点默为圆形实心点,色彩#e4e7ed

  • 属性type用于设置节点类型主题,生成不同色彩款式类el-timeline-item__node--[primary/success/warning/danger/info]
  • 属性size 用于设置预设节点尺寸(蕴含偏移量),生成el-timeline-item__node--[normal/large]
  • 属性 color 用于元素的内联款式 backgroundColor: color, 设置节点色彩。
  • 设置属性 icon值传入icon 类名就可间接间接使⽤图标。
  • 提供了具名 dot 插槽用于自定义节点。
  • <!-- 实心圆点/图标 --><div v-if="!$slots.dot"class="el-timeline-item__node":class="[  `el-timeline-item__node--${size || ''}`,  `el-timeline-item__node--${type || ''}`]":style="{  backgroundColor: color}"><i v-if="icon"  class="el-timeline-item__icon"  :class="icon"></i></div><!-- 自定义 --><div v-if="$slots.dot" class="el-timeline-item__dot"><slot name="dot"></slot></div>

时间轴节点也是采纳相对布局,元素的尺寸和布局偏移在款式类el-timeline-item__node--normalel-timeline-item__node--large定义。

.el-timeline-item__node {  position: absolute;  background-color: #e4e7ed;  border-radius: 50%; }// 尺寸及布局偏移.el-timeline-item__node--normal {  left: -1px;  width: 12px;  height: 12px;}.el-timeline-item__node--large {  left: -2px;  width: 14px;  height: 14px;}

信息内容

时间轴内容蕴含工夫戳和信息,通过属性placement可设置工夫戳地位 top / bottom

信息内容应用匿名插槽渲染。工夫戳地位没有应用相对布局或flex布局。当设置值top时,工夫戳内容在信息内容之前;设置值bottom时,信息内容就会在工夫戳内容之前。浏览器渲染时会恪守html排列程序。

<!-- 时间轴内容 --><div class="el-timeline-item__wrapper">  <!-- 工夫戳地位 top-->  <div v-if="!hideTimestamp && placement === 'top'"    class="el-timeline-item__timestamp is-top">    {{timestamp}}  </div>  <!-- 内容 -->  <div class="el-timeline-item__content">    <slot></slot>  </div>  <!-- 工夫戳地位 bottom-->  <div v-if="!hideTimestamp && placement === 'bottom'"    class="el-timeline-item__timestamp is-bottom">    {{timestamp}}  </div></div>

款式实现

组件款式源码 packages\theme-chalk\src\timeline.scsspackages\theme-chalk\src\timeline-item.scss应用混合指令嵌套生成组件款式。

// packages\theme-chalk\src\timeline.scss// 生成 .el-timeline@include b(timeline) {  // ...    // .el-timeline .el-timeline-item:last-child .el-timeline-item__tail  & .el-timeline-item:last-child {    & .el-timeline-item__tail {      // ...    }  }} // packages\theme-chalk\src\timeline-item.scss// 生成 .el-timeline-item @include b(timeline-item) {  // ...   // 生成  .el-timeline-item__wrapper  @include e(wrapper) {    // ...  }  // 生成 .el-timeline-item__tail  @include e(tail) {    // ...  }  // 生成 .el-timeline-item__icon  @include e(icon) {    // ...  }  // 生成 .el-timeline-item__node  @include e(node) {    // ...    // 生成 .el-timeline-item__node--normal    @include m(normal) {      // ...    }    // 生成  .el-timeline-item__node--large       @include m(large) {      // ...    }    // 生成 .el-timeline-item__node--[primary/success/warning/danger/info]    @include m(primary) {      // ...    }     // success/warning/danger/info ....      }  // 生成 .el-timeline-item__dot  @include e(dot) {    // ...  }  // 生成 .el-timeline-item__content   @include e(content) {    // ...  }  // 生成 .el-timeline-item__timestamp  @include e(timestamp) {    // ...    // 生成 .el-timeline-item__timestamp.is-top     @include when(top) {      // ...    }    // 生成 .el-timeline-item__timestamp.is-bottom    @include when(bottom) {      // ...    }  }}

关注专栏

如果本文对您有所帮忙请关注➕、 点赞、 珍藏⭐!您的认可就是对我的最大反对!