本篇文章记录仿写一个el-divider组件细节,从而有助于大家更好了解饿了么ui对应组件具体工作细节。本文是elementui源码学习仿写系列的又一篇文章,后续闲暇了会不断更新并仿写其余组件。源码在github上,大家能够拉下来,npm start运行跑起来,联合正文有助于更好的了解。github仓库地址如下:https://github.com/shuirongsh…
组件需要剖析
对于tag
组件,次要是用于展现一些标签信息,个别的需要有如下:
tag标签文字色彩自定义
tag标签背景色自定义
tag标签边框色彩自定义
管制是否展现敞开tag标签小叉号图标
自定义tag标签的文字色彩、背景色、边框色彩
标签的大小类型(大型、中型、小型标签)
饿了么官网应用的是render
函数编写的el-tag
,所以这里咱们也应用render
函数去写。整体来说,这个组件还是比较简单的。留神一下jsx
的语法即可。
组件效果图
看成果的话,间接复制粘贴运行跑起来,联合正文更有助于了解。最残缺的代码在github上哦
应用之代码
<template>
<div>
<my-divider lineType="dotted" content-position="left"
>默认标签款式</my-divider
>
<my-tag>默认标签</my-tag>
<my-tag closable>默认标签可敞开</my-tag>
<my-divider lineType="dotted" content-position="left"
>类型标签款式</my-divider
>
<my-tag type="primary">类型标签primary</my-tag>
<my-tag type="primary" closable>类型标签primary可敞开</my-tag>
<my-tag type="success">类型标签success</my-tag>
<my-tag type="success" closable>类型标签success可敞开</my-tag>
<my-tag type="info">类型标签info</my-tag>
<my-tag type="info" closable>类型标签info可敞开</my-tag>
<my-tag type="warning">类型标签warning</my-tag>
<my-tag type="warning" closable>类型标签warning可敞开</my-tag>
<my-tag type="danger">类型标签danger</my-tag>
<my-tag type="danger" closable>类型标签danger可敞开</my-tag>
<my-divider lineType="dotted" content-position="left"
>自定义标签款式</my-divider
>
<my-tag color="blue">标签文字色彩自定义</my-tag>
<my-tag bgColor="pink">标签背景色彩自定义</my-tag>
<my-tag borderColor="red">标签边框色彩自定义</my-tag>
<my-divider lineType="dotted" content-position="left"
>中等标签及大型标签</my-divider
>
<my-tag type="primary" sizeType="big" closable>大型标签</my-tag>
<my-tag type="success" sizeType="medium" closable>中型标签</my-tag>
<my-tag style="cursor: pointer" type="info" sizeType="small"
>默认(小型)标签,sizeType="small"写不写都行的</my-tag
>
<my-divider lineType="dotted" content-position="left"
>动静编辑标签</my-divider
>
<my-tag
v-for="(item, index) in arr"
closable
@close="handleClose(item)"
@click="handleClick(item)"
type="success"
:key="item"
>{{ item }}</my-tag
>
<el-input
v-model.trim="val"
@blur="blurFn"
size="mini"
style="width: 120px"
></el-input>
</div>
</template>
<script>
export default {
data() {
return {
arr: ["标签一", "标签二", "标签三"],
val: "",
};
},
methods: {
blurFn() {
if (this.val === "") return;
this.arr.push(this.val);
this.val = "";
},
handleClose(tag) {
// 找到点击的是哪个
let i = this.arr.findIndex((item) => {
return tag === item;
});
// 删除之
this.arr.splice(i, 1);
},
handleClick(tag) {
console.log("点击标签啦", tag);
},
},
};
</script>
封装组件的代码
<script>
const typeArr = ["primary", "success", "info", "warning", "danger"]; // 标签类型数组
const sizeType = ["big", "medium", "small"]; // 标签大小数组
export default {
name: "myTag",
props: {
closable: Boolean, // 是否展现可敞开的小叉号图标
color: String, // 标签文字的色彩
bgColor: String, // 标签背景色
borderColor: String, // 标签边框色彩
// 五种标签类型
type: {
type: String,
validator(val) {
return typeArr.includes(val); // 校验类型
},
},
// 三种标签大小
sizeType: {
type: String,
validator(val) {
return sizeType.includes(val); // 校验大小
},
},
},
methods: {
handleClose(event) {
/* 阻止冒泡避免与下方的handleClick办法抵触,要不然点击close敞开小图标,也会
触发下方click事件的执行。即:内层事件阻止冒泡与外层事件隔离开来 */
event.stopPropagation();
this.$emit("close", event);
},
handleClick(event) {
this.$emit("click", event);
},
},
// render函数jsx语法更加灵便
render(h) {
// 1. 筹备款式类 class绑定classArr数组罕用款式,style绑定props变量自定义款式
const classArr = ["my-tag", this.type, this.sizeType];
// 2. 筹备一个dom,并绑定相干class、style、event
const tagEl = (
<span
class={classArr}
style={{
backgroundColor: this.bgColor,
color: this.color,
borderColor: this.borderColor,
}}
on-click={this.handleClick}
>
{/* 默认插槽渲染内容即my-tag标签中的文字 */}
{this.$slots.default}
{/* 三元表达式条件管制是否渲染敞开小图标 */}
{this.closable ? (
<span class="close-tag" on-click={this.handleClose}>
x
</span>
) : null}
</span>
);
// 3. 返回render渲染之
return <transition name="el-fade-in">{tagEl}</transition>;
// 应用饿了么UI自带的突变过渡动画
},
};
</script>
<style scoped>
/* 默认标签款式 */
.my-tag {
display: inline-block;
box-sizing: border-box;
padding: 0 8px;
color: #252525;
background-color: #fafafa;
border: 1px solid #d9d9d9;
border-radius: 4px;
font-size: 12px;
white-space: nowrap;
height: auto;
line-height: 20px;
margin: 0 8px 8px 0;
}
/* 标签敞开小叉号款式 */
.close-tag {
position: relative;
margin-left: 5px;
cursor: pointer;
display: inline-block;
transform: translateY(-6%);
}
/* 5种类型标签款式 */
.primary {
color: #409eff;
border: 1px solid #d9ecff;
background-color: #ecf5ff;
}
.success {
background-color: #f0f9eb;
border-color: #e1f3d8;
color: #67c23a;
}
.info {
background-color: #f4f4f5;
border-color: #e9e9eb;
color: #909399;
}
.warning {
background-color: #fdf6ec;
border-color: #faecd8;
color: #e6a23c;
}
.danger {
background-color: #fef0f0;
border-color: #fde2e2;
color: #f56c6c;
}
/* 默认小型标签款式,可选值为中等标签、大型标签。当然这里没有small,因为small就是默认的 */
.big {
padding: 4px 10px;
}
.medium {
padding: 2px 10px;
}
</style>
总结
- 大家封装本人的组件的时候,最好借鉴其余UI组件库,比方这里仿写
el-tag
也是参照了antD
的设计形式。 - 再一个就是仿写组件,不是把官网的组件全副照搬过去,而是适当取舍,保留比拟罕用的组件性能,临时摒弃冷门组件性能,并退出本人公司罕用的性能,以及本人的了解
- 如果有遇到冷门的组件性能,能够思考再独自封装一个组件去解决
- 组件须要集成一些性能,然而不能集成十分多的性能,高内聚
- 自己程度无限,说的不肯定对,仅供各位道友参考
^_^
发表回复