携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第3天,点击查看活动详情
传统的a标签样式太过简陋,所以这篇文章将为我们组件库实现一个文字超链接Link
组件。首先要做的就是目录结构的创建(和前面组件目录一致),如下图
当然如果你想更深入的了解Vue3组件库的搭建的话可以关注这个专栏->从零搭建vue3组件库系列专栏 将不断更新一些组件的实现方法。
接下来就开始实现我们组件库的第三个组件Link
组件
基础用法
首先我们先将写出我们Link
组件的基本框架,link.vue
如下
<template> <a class="k-link"> <slot /> </a> </template> <script lang="ts"> import './style/index.less' import { defineComponent } from 'vue' export default defineComponent({ name: 'k-link', setup(props) { return { } } }); </script>
然后去除a
标签的默认样式以及给Link
标签加上基础样式 style/index.less
如下
.k-link { 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: 0; font-size: 14px; font-weight: 500; }
最后我们统一导出
Link
组件,其中目录结构如下图
- link/index.ts
这里我们已经将withInstall
封装成了一个包为我们组件提供install
属性
import link from './link.vue' import { withInstall } from '@kitty-ui/utils' const Link = withInstall(link) export default Link
- src/index.ts
这里集中导出所有组件
export { default as Button } from './button' export { default as Icon } from './Icon' export { default as Link } from './link'
- components/index.ts
这里分别导出单个组件,以及默认导出为所有组件赋予install函数的对象便于全局导入我们的组件库,app.use(xxx)
import * as components from './src/index' export * from './src/index' export default { install: (app: any) => { for (const comkey in components) { app.component((components as any)[comkey].name, (components as any)[comkey]) } } }
然后根目录下执行pnpm run exm:dev
启动我们的测试组件实例项目examples
,这里的做了一个脚本配置
然后在examples/app.vue
中引入Link
组件
<template> <div> <Link>link</Link> </div> </template> <script lang="ts" setup> import { Link } from 'kitty-ui' </script> <style lang="less"> </style>
此时页面上已经展示了我们的
Link
组件,我们便可继续开发Link
组件的其它功能了。
继承a标签原生属性
接下来我们要做的是将原生a
标签上的属性原封不动的复制到我们的Link
组件上,比如href
、 target
等。我们可以使用vue3中的useAttrs
获取传来的所有属性然后绑定在组件上。实现方式如下
<template> <a v-bind="attrs" class="k-link"> <slot /> </a> </template> <script lang="ts"> import './style/index.less' import { defineComponent, useAttrs } from 'vue' export default defineComponent({ name: 'k-link', setup(props) { const attrs = useAttrs() console.log(attrs) return { attrs } } }); </script>
然后在app.vue
进行一个测试
<template> <div> <Link href="https://juejin.cn/post/7121381989864701982">link</Link> </div> </template> <script lang="ts" setup> import { Link } from 'kitty-ui' </script> <style lang="less"> </style>
你会发现点击便可跳转到对应链接。
根据不同type展示不同颜色
接下来实现的其实和Button
组件差不多,更具传来的不同type
展示不同效果。首先我们在types.ts
中定义组件的属性:
import { ExtractPropTypes } from 'vue' export const LinkType = ['primary', 'success', 'info', 'warning', 'danger'] export const linkProps = { type: { type: String, validator(value: string) { return LinkType.includes(value) } }, } export type LinkProps = ExtractPropTypes<typeof linkProps>
然后我们在link.vue
中使用,然后用计算属性实现不同type对应不同类名
<template> <a v-bind="attrs" class="k-link" :class="styleClass"> <slot /> </a> </template> <script lang="ts"> import './style/index.less' import { linkProps } from './types' import { defineComponent, useAttrs, computed } from 'vue' export default defineComponent({ name: 'k-link', props: linkProps, setup(props) { const attrs = useAttrs() const styleClass = computed(() => { return { [`k-link--${props.type}`]: props.type, } }) return { attrs, styleClass } } }); </script>
同时我们在style/index.less
中定义primary
类型以及它的hover(其它type实现方式一样,这里就不一一展示了)
... .k-link--primary { color: #409eff; } .k-link--primary:hover { color: #66b1ff; }
展示如下
到这里Link
组件的基础用法便实现了,接下来开始实现它的禁用状态
禁用状态
它的实现和和type差不多,同样根据disabled
属性来赋予不同类名,这里同样只展示一个primary
的禁用状态,奇遇type实现方式一致
- types.ts
... export const linkProps = { type: { type: String, validator(value: string) { return LinkType.includes(value) } }, disabled: Boolean } ...
- link.vue
... const styleClass = computed(() => { return { [`k-link--${props.type}`]: props.type, 'is-disabled': props.disabled } }) ...
- style/index.less
... .k-link.is-disabled { cursor: not-allowed; } .k-link.is-disabled { cursor: not-allowed; } .k-link--primary.is-disabled { color: #a0cfff; }
最后展示如下
下划线
我们使用underline
来控制我们组件是否展示下划线,如果underline
为true
我们便给组件添加个类名is-underline
,并给is-underline
添加个伪类after
- types.ts
... export const linkProps = { type: { type: String, validator(value: string) { return LinkType.includes(value) } }, disabled: Boolean, underline: Boolean } ...
- link.vue
... const styleClass = computed(() => { return { [`k-link--${props.type}`]: props.type, 'is-disabled': props.disabled, 'is-underline': props.underline, } }) ...
- style/index.less
.k-link.k-underline:hover:after { content: ""; position: absolute; left: 0; right: 0; height: 0; bottom: 0; border-bottom: 1px solid #409eff; }
在app.vue中使用
<Link type="primary" underline>主要链接</Link>
此时鼠标移入便出现了下划线
直接使用
组件库代码已经上传到gitee,如果你感兴趣的话可以直接点击->kittyui 使用(记得给个star哦~~~~ ),然后你只需要以下几步便可启动项目、组件库文档以及本地调试项目
- 安装
pnpm npm i pnpm -g
- 安装所有依赖
pnpm install
- 启动本地调试vue3项目
pnpm run exm:dev
- 打包
pnpm run build
- 启动文档
pnpm run docs:dev
- 打包文档
pnpm run docs:build
- 启动打包后文档服务
pnpm run docs:serve