本篇文章记录仿写一个
el-button
组件细节,从而有助于大家更好理解饿了么ui对应组件具体工作细节。本文是elementui源码学习仿写系列的又一篇文章,后续空闲了会不断更新并仿写其他组件。源码在github上,大家可以拉下来,npm start运行跑起来,结合注释有助于更好的理解
网站效果演示:ashuai.work:8888/#/myButton
GitHub仓库地址:github.com/shuirongshu…
按钮用于点击,一般是做事件的响应。
默认按钮很简单,只是写一个最普通的样式即可
.myButton {display: inline-flex;align-items: center;justify-content: center;white-space: nowrap;box-sizing: border-box;padding: 12px 16px;background-color: rgba(0, 0, 0, 0.1);color: #222;border: none;cursor: pointer;user-select: none; // 不让选中文字transition: all 0.3s;font-size: 14px;
}
// 悬浮效果
.myButton:hover {background-color: rgba(0, 0, 0, 0.2);
}
// 按中效果
.myButton:active {background-color: rgba(0, 0, 0, 0.3);
}
笔者这里是将悬浮的效果和按中的效果,设置背景色越来越深。这样的话,看着效果比较明显
所谓按钮的主题,就是添加不同的类名,比如primary
主题的按钮,就加上.primary
类名、success
主题的按钮,就加上.success
类名。然后使用动态class
去添加即可(这里使用动态class的数组用法)。如:
变量type
的值源自于使用按钮组件时,传递进来的type
参数
const typeArr = ["","primary","success","warning","error","text","dangerText",
];props:{type: { // 按钮主题类型type: String,validator(val) {return typeArr.includes(val); // 这里可以加一个校验函数,其实不加也行},},
}
然后给不同type值加上对应的样式即可。如下:
// primary样式
.primary {background-color: #1867c0;color: #fff;
}
.primary:hover {background-color: #0854ac;
}
.primary:active {background-color: #033d7f;
}// success样式
.success {background-color: #19be6b;color: #fff;
}
.success:hover {background-color: #0ea459;
}
.success:active {background-color: #008140;
}// warning样式
.warning {background-color: #ffc163;color: #fff;
}
.warning:hover {background-color: #db952d;
}
.warning:active {background-color: #b97b1d;
}// 等等type值样式...
按钮大小可以使用padding
值的大小去控制,也可以直接使用zoom
缩放做控制
这里使用动态style
搭配计算属性的方式去控制,如下代码:
// 不同的大小指定不同的缩放程度
const sizeObj = {small: 0.85,middle: 1,big: 1.2,
};props:{ size: String }computed: {styleCal() {return {zoom: sizeObj[this.size] // zoom缩放的值大小取决于传递进来的size值}}
}
按钮禁用disable
没啥好说的,主要是要注意loading
的时候,也要禁用掉,loading
加载的时候,不允许用户再点击。
props:{loading:Boolean
}
这里注意一下,按钮禁用的样式也是通过动态class加上的,请往下看
注意加载时样式和加载按钮图标出来的时候,将其他的图标给隐藏起来。(同一时刻,只能有一个按钮图标,这样保证按钮加载时简洁一些)
默认从左往右排列(图标在左侧、文字在右侧),这里我们可以使用弹性盒的方向flexDirection
属性,来控制从左往右还是从右往左排列
styleCal() {// 控制缩放和指定默认圆角以及设置图标在文字左侧还是右侧let styleObj = {zoom: sizeObj[this.size],borderRadius: "5px",flexDirection: this.rightIcon ? "row-reverse" : "row",};return styleObj;
},
这两个也很简单,
然后动态控制一下即可
按钮组注意事项:
:first-of-type
的左上角和左下角的圆角设置一下last-of-type
的右上角和右下角的圆角设置一下border-right
做分割线// 附上按钮组样式
.myButtonGroup > .myButton {border-radius: unset !important; // 给所有的按钮都去掉圆角border-right: 1px solid #fff; // 给按钮加上分隔线条
}
// 第一个按钮左侧圆角
.myButtonGroup > .myButton:first-of-type {border-top-left-radius: 5px !important; border-bottom-left-radius: 5px !important;
}
// 最后一个按钮的右侧圆角
.myButtonGroup > .myButton:last-of-type {border-top-right-radius: 5px !important;border-bottom-right-radius: 5px !important;border-right: none; // 同时,清除最后一个按钮的右侧边框
}
复制粘贴即可使用,如果道友觉得代码帮忙到了您,欢迎给咱github仓库一个star哈😄
单个按钮
{clickBtn(item, e);}">{{ item.name }}
按钮组
上一页 下一页