一、组件库介绍
有兴趣的同学 可以先着手看源码,之前写的一系列开源组件库项目(有帮助的同学也帮忙点个star👍)
名称 | 官网 | github |
---|---|---|
tinkerbell-ui(vue2.0) | http://tinkerbell.top | https://github.com/hanbingxu82/tinkerbell-ui |
tinkerbell-ui(vue3.0) | — | https://github.com/hanbingxu82/tinkerbell-ui-next |
tinkerbell-ui(react-hook) | — | https://github.com/hanbingxu82/tinkerbell-ui-react |
二、Link组件流程介绍
其实谈到文本链接组件,我们可以参考向element、antd这些其实可以把这些看成是一个个的文字按钮组件,只不过底层就是使用a标签去实现的,又或者,我不想让其拥有a标签的href属性的话,底层完全就可以使用span标签来包裹文本,总的来说其实就相当于对文本进行了一个封装,我们可以通过属性进行判断到底是一个链接组件,还是一个单纯类似按钮功能的文本样式组件,简单的来讲我们只需要对其进行一个颜色封装即可,当然主要的也是要捋清楚代码该如何去写:
1、首先肯定还是需要来对其进行一个判断,判断Link组件的类型到底是文本呢?还是链接呢?所以我们需要一个type属性,这是其一。
2、其次,我们可以根据文本内容加入 Icon 图标,让其内容多元化,就不需要再去手动在前置位,后置位填写 i 标签写class样式了,再有当然我们也要将 disabled 禁用属性添加上 实现对应的权限功能。
3、最后也是归笼一下我们的属性功能等,因为如果设置了a标签,默认a标签是带有着下划线的,那么我也同样也要判断是否带有着下划线?
type: string // 类型 primary / success / warning / danger / info
href: string // 原生 href 属性
target: string // a标签 原生target属性
disabled: boolean // 是否禁用状态
underline: true // 是否下划线
icon: string // 图标类名
三、代码详解
3.1、index.tsx
import React, { useState, useEffect } from 'react'
import './index.scss'
interface Iprops {
type: string // 类型 primary / success / warning / danger / info
href: string // 原生 href 属性
target: string // a标签 原生target属性
disabled: boolean // 是否禁用状态
underline: true // 是否下划线
icon: string // 图标类名
}
function Link(props: any) {
const [tbType, setTbType] = useState('')
const [tbDisabled, setTbDisabled] = useState('')
const [tbUnderline, setTbUnderline] = useState('')
const [tbIcon, setTbIcon] = useState('')
const {
type = '',
href = '',
target = '_blank',
disabled = false,
underline = true,
icon = ''
}: Iprops = props
// 类似于 componentDidMount 和 componentDidUpdate:
useEffect(() => {
Ptype()
PDisabled()
Punderline()
Picon()
}, [])
// 页面加载判断当前按钮类型
function Ptype() {
if (type == 'primary') {
setTbType('a_primary')
} else if (type == 'success') {
setTbType('a_success')
} else if (type == 'info') {
setTbType('a_info')
} else if (type == 'warning') {
setTbType('a_warning')
} else if (type == 'danger') {
setTbType('a_danger')
}
}
// 判断是否是禁用
function PDisabled() {
if (disabled) {
setTbDisabled(' is_disabled')
} else {
setTbDisabled(' ')
}
}
// 判断是否有下划线
function Punderline() {
console.log(underline)
if (!underline) {
setTbUnderline(' is_underline')
} else {
setTbUnderline(' ')
}
}
// 页面加载判断是否为图标按钮
function Picon() {
if (icon) {
setTbIcon(' iconfont ' + icon)
} else {
setTbIcon('')
}
}
if (!tbIcon && href) {
return (
<a
{...props}
target={target}
href={href}
className={`tb-link ${tbType} ${tbDisabled} ${tbUnderline}`}
>
{props.children}
</a>
)
} else if (tbIcon && href) {
return (
<a
{...props}
target={target}
href={href}
className={`tb-link ${tbIcon} ${tbType} ${tbDisabled} ${tbUnderline}`}
>
{props.children}
</a>
)
} else if (tbIcon && !href) {
return (
<span
{...props}
target={target}
className={`tb-link ${tbIcon} ${tbType} ${tbDisabled} ${tbUnderline}`}
>
{props.children}
</span>
)
} else {
return (
<span
{...props}
className={`tb-link ${tbType} ${tbDisabled} ${tbUnderline}`}
>
{props.children}
</span>
)
}
}
export default Link
3.2、index.scss
@import '../../style/variables.scss';
/* is_disabled 禁用 */
.is_disabled {
pointer-events: none;
/* cursor:not-allowed!important; */
opacity: 0.6;
}
/* is_underline 下划线 */
.is_underline {
text-decoration: none !important;
}
.tb-link.iconfont {
vertical-align: baseline;
}
.tb-link {
color: #606266;
display: inline-flex;
flex-direction: row;
align-items: center;
justify-content: center;
vertical-align: middle;
position: relative;
text-decoration: none;
outline: none;
cursor: pointer;
padding: 1px;
font-size: 14px;
font-weight: 500;
box-sizing: border-box;
-webkit-tap-highlight-color: #606266;
}
.tb-link:focus,
.tb-link:hover {
color: $color-primary-light1;
text-decoration: underline;
}
/* .tb-link:visited,
.tb-link:active {
text-decoration: none;
} */
/* type样式 */
.tb-link.a_primary {
color: $color-primary;
}
.tb-link.a_primary:focus,
.tb-link.a_primary:hover {
color: $color-primary-light1;
}
.tb-link.a_success {
color: $color-success;
}
.tb-link.a_success:focus,
.tb-link.a_success:hover {
color: $color-success-light1;
}
.tb-link.a_info {
color: $color-info;
}
.tb-link.a_info:focus,
.tb-link.a_info:hover {
color: $color-info-light1;
}
.tb-link.a_warning {
color: $color-warning;
}
.tb-link.a_warning:focus,
.tb-link.a_warning:hover {
color: $color-warning-light1;
}
.tb-link.a_danger {
color: $color-danger;
}
.tb-link.a_danger:focus,
.tb-link.a_danger:hover {
color: $color-danger-light1;
}
3.3、variables.scss
// $font-path : './fonts'
/* Color
-------------------------- */
$color-white : #FFFFFF;
$color-white-light : rgba(255, 255, 255, 0.65);
$color-white-light2 : rgba(255, 255, 255, 0.35);
$color-primary : #1089ff;
$color-primary-light1 : mix(#FFFFFF, $color-primary, 20%);
$color-primary-light2 : mix(#FFFFFF, $color-primary, 40%);
$color-primary-light3 : mix(#FFFFFF, $color-primary, 60%);
$color-primary-light4 : mix(#FFFFFF, $color-primary, 80%);
$color-primary-light5 : mix(#FFFFFF, $color-primary, 90%);
$color-primary-light6 : mix(#FFFFFF, $color-primary, 95%);
$color-primary-active : mix(#000000, $color-primary, 10%);
$color-success :#52c41a;
$color-success-light1 : mix(#FFFFFF, $color-success, 20%);
$color-success-light2 : mix(#FFFFFF, $color-success, 40%);
$color-success-light3 : mix(#FFFFFF, $color-success, 60%);
$color-success-light4 : mix(#FFFFFF, $color-success, 80%);
$color-success-light5 : mix(#FFFFFF, $color-success, 90%);
$color-success-light6 : mix(#FFFFFF, $color-success, 95%);
$color-success-active : mix(#000000, $color-success, 10%);
$color-info : #35495E;
$color-info-light1 : mix(#FFFFFF, $color-info, 20%);
$color-info-light2 : mix(#FFFFFF, $color-info, 40%);
$color-info-light3 : mix(#FFFFFF, $color-info, 60%);
$color-info-light4 : mix(#FFFFFF, $color-info, 80%);
$color-info-light5 : mix(#FFFFFF, $color-info, 90%);
$color-info-light6 : mix(#FFFFFF, $color-info, 95%);
$color-info-active : mix(#000000, $color-info, 10%);
$color-warning : #fea638;
$color-warning-light1 : mix(#FFFFFF, $color-warning, 20%);
$color-warning-light2 : mix(#FFFFFF, $color-warning, 40%);
$color-warning-light3 : mix(#FFFFFF, $color-warning, 60%);
$color-warning-light4 : mix(#FFFFFF, $color-warning, 80%);
$color-warning-light5 : mix(#FFFFFF, $color-warning, 90%);
$color-warning-light6 : mix(#FFFFFF, $color-warning, 95%);
$color-warning-active : mix(#000000, $color-warning, 10%);
$color-danger : #ff4d4f;
$color-danger-light1 : mix(#FFFFFF, $color-danger, 20%);
$color-danger-light2 : mix(#FFFFFF, $color-danger, 40%);
$color-danger-light3 : mix(#FFFFFF, $color-danger, 60%);
$color-danger-light4 : mix(#FFFFFF, $color-danger, 80%);
$color-danger-light5 : mix(#FFFFFF, $color-danger, 90%);
$color-danger-light6 : mix(#FFFFFF, $color-danger, 95%);
$color-danger-active : mix(#000000, $color-danger, 10%);
/* text-color
-------------------------- */
$color-text-primary : rgba(0, 0, 0, .85);
$color-text-default : rgba(0, 0, 0, .65);
$color-text-secondary : rgba(0, 0, 0, .45);
$color-text-disabled : rgba(0, 0, 0, .25);
$color-text-placeholder : #C0C4CC;
$btn-disable-color : #c5c8ce;
$color-disabled-bg:rgb(245, 245, 245);
$color-disabled-border:rgb(217, 217, 217);
/* bg-color
-------------------------- */
$color-bg-fa : #fafafa;
$color-select-hover : #f5f5f5;
$color-effect-shadow : alpha($color-primary);
$color-input-shadow : alpha($color-primary);
$color-input-error-shadow : alpha($color-danger);
/* border
-------------------------- */
$border-color-base : #d9d9d9;
$border-color-light : #f0f0f0;
$border-base : 1px solid $border-color-base;
$border-width:1px;
$border-base-light : 1px solid $border-color-light;
$border-table : 1px solid #e8eaec;
$border-table-color : #e8eaec;
/* radius font-size
-------------------------- */
$border-base-radius : 2px;
$base-font-size : 14px;
$header-font-size : 16px;
/* height
-------------------------- */
$large-height : 36px;
$default-height : 32px;
$small-height : 28px;
$mini-height : 24px;
$base-line-height : 1.5715;
$animation-duration-slow : 0.3s;
$animation-duration-base : 0.2s;
$animation-duration-fast : 0.1s;
// placeholder
$placeholder-color : #c0c4cc;
四、效果呈现
至此效果实现
react 官网持续开发中,也请大家持续关注博主
结语
✨ 每天创作一点点
✨ 开心快乐一整天
✨ 点赞关注加收藏
✨ 美好一天又一天
铁铁们 感谢支持 我需要你们的三连 👍👍👍