本篇文章记录仿写一个el-timeline
组件细节,从而有助于大家更好了解饿了么ui对应组件具体工作细节。本文是elementui源码学习仿写系列的又一篇文章,后续闲暇了会不断更新并仿写其余组件。源码在github上,大家能够拉下来,npm start运行跑起来,联合正文有助于更好的了解。github仓库地址如下:github.com/shuirongshu…
组件剖析
组件形成局部
工夫线组件形成局部可分为四局部:
- 工夫线小圆点
- 工夫线竖线条
- 工夫戳
- 具体内容详情
如下图:
所以针对工夫线组件的需要,次要是从这四个角度去管制。个别工夫线组件需要如下:
组件需要剖析
对于分割线的组件,个别应用的场景需要有:
- 比方依照工夫线正序或顺叙的展现(如:日志记录)
- 比方默认的工夫线小圆点的款式色彩,以及能够自定义色彩(这里默认蓝色圆环)
- 比方也能够应用小图标代替工夫线小圆点(例,应用饿了么图标)
- 应用了饿了么小图标,有时候还须要给图标上色
- 比方管制工夫戳和具体内容详情的地位(这里默认工夫戳在上方,有时候工夫戳可能在下方)
- 有的时候,可能不须要展现工夫戳,只须要展现内容,所以要再加一个是否暗藏工夫戳的变量
对于官网组件的集体认识:
1.官网组件的provide
和inject
能够拿掉,如下图:
2.官网组件管制工夫戳地位用了两份dom
,能够更改为一份dom
搭配弹性盒方向管制
3.参考各方对仿写封装组件做一个简洁的解决
大家能够看一下antd和iview的工夫线组件,参数确实是比饿了么的工夫线组件少一些。
antd:https://ant.design/components...
iview:https://www.iviewui.com/view-...
个人观点不肯定对,仅供参考
组件中回顾知识点
温故而知新
this.$slots.default.reverse()
默认插槽数组this.$slots.default
,也是数组,所以也是能够应用数组的办法的。
这里管制工夫线的正序顺叙就是应用了,这个办法
:style中写四元表达式
冒号style其实也是能够写三元、或者四元或者更多元的,蕴含变量的表达式,如下:
<div class="dots" :style="{ border: elementIcon ? 'none' : borderColor ? `2px solid ${borderColor}` : '2px solid #1890ff', }" ></div>
粗心:通过:style
给class
为dots
的dom元素
设置border
边框款式,具体边框的值取决于elementIcon
和borderColor
这两个变量的值。
代码
演示的话,间接复制粘贴即可应用。当然残缺的代码在github上哦^_^
咱们先看一下效果图,再看一下代码
效果图
应用组件代码
<template> <div> <!-- 一般应用工夫正序排列 --> <button @click="reverse = !reverse">点击更改工夫线排序</button> <my-timeline style="margin-top: 6px" :reverse="reverse"> <my-timeline-item timestamp="2018-01-01" >2018年好像还在昨天一样</my-timeline-item > <my-timeline-item timestamp="2020-01-01" >2020就像刚刚过来一样</my-timeline-item > <my-timeline-item timestamp="2022-01-01" >2022年也曾经走完一半了</my-timeline-item > </my-timeline> <br /> <!-- 自定义工夫线圆点色彩或应用饿了么小图标 --> <my-timeline> <my-timeline-item v-for="(item, index) in timeArr" :key="index" :timestamp="item.timestamp" :borderColor="item.borderColor" :elementIcon="item.elementIcon" :iconColor="item.iconColor" >{{ item.content }}</my-timeline-item > </my-timeline> <br /> <!-- 管制工夫戳地位与是否暗藏工夫戳 --> <my-timeline> <my-timeline-item timestamp="2222-02-02" >默认工夫戳在文字上方</my-timeline-item > <my-timeline-item timestamp="3333-03-03" timeLocation="down" >通过timeLocation属性将工夫戳放在文字下方</my-timeline-item > <my-timeline-item timestamp="4444-04-04" hideTimestamp >若不想要工夫戳可应用hideTimestamp属性将其暗藏</my-timeline-item > </my-timeline> </div></template><script>export default { data() { return { reverse: false, timeArr: [ { timestamp: "2022-04-01", content: "默认工夫线小圆点款式", }, { timestamp: "2022-05-01", content: "更改工夫线小圆点色彩", borderColor: "red", }, { timestamp: "2022-04-01", content: "应用饿了么的小图标做为工夫线小圆点", elementIcon: "el-icon-view", }, { timestamp: "2022-07-01", content: "给饿了么的icon上色", elementIcon: "el-icon-location", iconColor: "green", }, ], }; },};</script>
myTimeline代码
<script>export default { name: "myTimeline", // 外层组件只承受一个参数即是否反转,内层组件的参数多一些 props: { reverse: { // 是否反转,即管制工夫排序形式 type: Boolean, default: false, // 默认从上往下 }, }, // 应用render函数渲染数据 render() { const reverse = this.reverse; const classes = { "my-timeline": true, "is-reverse": reverse, }; let slots = this.$slots.default || []; // 获取默认插槽数组 if (reverse) { slots = slots.reverse(); // 默认插槽数组,也是数组,所以也是能够应用reverse办法做反转的 } // 加上动静class 并传递默认插槽 return <ul class={classes}>{slots}</ul>; // 整体工夫线构造就是ul搭配li,一个li代表一项工夫线 },};</script><style lang="less">.my-timeline,.my-timeline .timeLineItem { list-style: none;}// 把最初一条竖向工夫线暗藏.my-timeline .timeLineItem:last-child .verticalLine { display: none;}</style>
myTimelineItem代码
<template> <li class="timeLineItem"> <!-- 垂直方向的线条 --> <div class="verticalLine"></div> <!-- 垂直方向的小圆点 --> <div class="dots" :style="{ border: elementIcon ? 'none' : borderColor ? `2px solid ${borderColor}` : '2px solid #1890ff', }" > <!-- 上述三元表达式意思: 当传了elementIcon时,阐明要应用饿了么UI的图标,即不应用border了,故为none; 当未传elementIcon时,再看是否传了borderColor了,若传了,就应用传递的borderColor作为 border-color的值,否则就应用默认的#1890ff为边框色 --> <i v-if="elementIcon" :style="{ color: iconColor }" :class="elementIcon" ></i> </div> <!-- 内容区,通过flex-direction管制工夫和细节的高低地位 --> <div class="content" :class="{ isSetTimeDown: timeLocation == 'down' }"> <!-- 内容区的工夫 --> <div class="contentTime" v-if="!hideTimestamp">{{ timestamp }}</div> <!-- 内容区的具体细节 --> <div class="contentDetail"> <slot></slot> </div> </div> </li></template><script>export default { name: "myTimelineItem", props: { // 工夫戳具体值 timestamp: String, // 是否暗藏工夫戳,只展现文字内容 hideTimestamp: { type: Boolean, default: false, // 默认显示工夫戳 }, // 工夫戳的地位,默认工夫戳地位在上方 timeLocation: String, // 指定工夫线条连贯的小圆点的边框色 borderColor: String, // 应用饿了么UI的图标替换节点小圆点,如 el-icon-more elementIcon: String, // 设置饿了么UI图标的色彩 iconColor: String, },};</script><style scoped lang="less">.timeLineItem { position: relative; // 定位管制工夫线和小圆点的地位细节 padding-bottom: 12px; .verticalLine { width: 2px; height: 100%; background-color: #e9e9e9; // 定位管制 position: absolute; top: 4px; } .dots { width: 12px; height: 12px; background-color: #fff; border-radius: 50%; // 通过定位将小圆点挪动到左侧工夫线上方 position: absolute; left: -5px; top: 4px; i { position: absolute; left: -2px; top: -2px; } } .content { padding-left: 24px; display: flex; // 通过弹性盒方向管制contentTime和contentDetail的高低地位(默认工夫在上方) flex-direction: column; .contentTime { margin-bottom: 6px; font-size: 13px; color: #666; } .contentDetail { margin-bottom: 6px; font-size: 14px; color: #333; } } // 是否让工夫在下方,取决于是否timeLocation的值是否为down .isSetTimeDown { flex-direction: column-reverse; }}</style>
如果对您有一点点帮忙的话,欢送github不吝star哦^O^