用vue3完成一个组件库 ------button

182 阅读3分钟

组件库是每个前端开发必须要接触的知识点了,开发一个属于自己的组件库是每个开发人员必须要经历的需求。第一次写文档,记录一下自己学习组件开发的过程,做笔记,前端必会的组件库,那就先从button组件开始。

用到的vue知识,利用vue开发组件库,button组件会用到vue相关的知识。

  • 父子传值
  • slot插槽
  • props校验

我自己认为开发组件就是要定义一些属性去让使用者方便快捷的修改dom,从而达到理想的页面展示效果。

其中button组件的属性如下:(根据需求在添加)

属性名属性类型默认值作用可选值
typeStringdefault按钮的样式,按需求添加primary/ success/ warning/ danger/ ...
plainBooleanfalse是否是朴素按钮false/ true
roundBooleanfalse是否是圆角按钮false/ true
circleBooleanfalse是否是圆形按钮false/ true
iconString''按钮中的图标字体图标类名
disabledBooleanfalse禁用false/ true

需要做的准备

在components目录下添加button组件.vue文件(文件名自定义,这里为 w-button.vue)

button目录位置.jpg

w-button.vue文件初始代码结构:

<template>
    <button class="w-button">
    <span>
        <slot></slot>
    </span>
    </button>
</template>

<script lang="ts">
export default {
    name:"WButton",
    props: {
    }

}
</script>

<style lang="scss" scoped>
</style>

其中的slot标签为插槽,当使用该组件时组件标签中的文字节点,可替换slot标签。

main.ts中的代码如下:

import { createApp } from 'vue'
import App from './App.vue'

import WButton from './components/w-button.vue';


const app = createApp(App);
app.component(WButton.name, WButton);

app.mount('#app')

先引进w-button组件文件,在用app.component()方法定义全局组件。

这时我们就可以在App.vue文件中查看w-button组件效果方便修改:

<template>
  <div>
    <w-button>点击</w-button>
  </div>
</template>

<script lang="ts">

export default {
  components: { },
}
</script>

<style lang="scss">
</style>

页面效果如下:

image.png

此时什么样式都没有,我们可以添加一下我们风格的样式:(这是从element ui样式,我们也可以随意变成我们自己想要的样式)

 .w-button {
    display: inline-block;
    line-height: 1;
    white-space: nowrap;
    cursor: pointer;
    background: #fff;
    border: 1px solid #dcdfe6;
    color: #606266;
    -webkit-appearance: none;
    text-align: center;
    box-sizing: border-box;
    outline: none;
    margin: 0;
    transition: .1s;
    font-weight: 500;
    -moz-user-select: none;
    -webkit-user-select: none;
    -ms-user-select: none;
    padding: 12px 20px;
    font-size: 14px;
    border-radius: 4px;
    &:hover {
        color: #409eff;
        border-color: #c6e2ff;
        background-color: #ecf5ff;
    }
    &:focus {
        color: #409eff;
        border-color: #c6e2ff;
        background-color: #ecf5ff;
    }
    &:active {
        color: #3a8ee6;
        border-color: #3a8ee6;
        outline: none;
    }
 }

此时我们的样式如下:

未选中时

image.png

hover时

image.png

点击过后样式与hover时一样就不展示了。

button按钮一般就设置三种状态下的样式就好了(默认 hover 点击后)。

type属性

此时我们就可以来完成第一个属性值type的代码了:

在w-button.vue组件中

<template>
    <button class="w-button" :class="[`w-button--${type}`]">
    <span>
        <slot></slot>
    </span>
    </button>
</template>

<script lang="ts">
export default {
    name:"WButton",
    props: {
        type: {
            type: String,
            default: 'default'
        },
    }

}
</script>

在button标签上我们利用添加动态类名的方式,给button标签上添加新的类名,以primary类型为例当我们在使用组件时:

<w-button type="primary">点击</w-button>

type属性就会传到w-button子组件中,我们利用props给type定义了类型和默认值,此时在dom结构中就给button属性添加上了w-button--primary类名,我们就可以给定css来给primary类型添加属于他的样式了。

image.png

 .w-button--primary {
    color: #fff;
    background-color: #409eff;
    border-color: #409eff;
    &:hover {
      background: #66b1ff;
      border-color: #66b1ff;
      color: #fff;
    }
    &:focus {
      background: #66b1ff;
      border-color: #66b1ff;
      color: #fff;
    }
    &:active {
      outline: none;
    }
 }

添加样式后展示效果为:

image.png

这样我们就可以给success/ warning/ danger/等类型添加不同的样式,这里就不一一展示了。

plain属性

在w-button.vue中

<template>
    <button class="w-button" :class="[`w-button--${type}`,
     {'is-plain':plain},
    ]">
    <span>
        <slot></slot>
    </span>
    </button>
</template>

<script lang="ts">
export default {
    name:"WButton",
    props: {
        type: {
            type: String,
            default: 'default'
        },
        plain: {
            type: Boolean,
            default: false
        },
    }

}
</script>

组件使用中:(相当于 :panin="true")

<w-button plain type="primary">点击</w-button>

这样button元素就多了一个is-plain属性

image.png

同上写is-plain的样式以primary类型为例

 .w-button--primary.is-plain {
    color: #409eff;
    background: #ecf5ff;
    border-color: #b3d8ff;
    &:hover {
      background: #409eff;
      border-color: #409eff;
      color: #fff;
    }
    &:focus {
      background: #409eff;
      border-color: #409eff;
      color: #fff;
    }
 }

展示如下:

默认

image.png

hover image.png

plain属性circle属性 同上直接上代码

w-button.vue

<template>
    <button class="w-button" :class="[`w-button--${type}`,
     {'is-plain':plain},
     {'is-round':round},
     {'is-circle':circle}
    ]">
    <span>
        <slot></slot>
    </span>
    </button>
</template>

<script lang="ts">
export default {
    name:"WButton",
    props: {
        type: {
            type: String,
            default: 'default'
        },
        plain: {
            type: Boolean,
            default: false
        },
        round: {
            type: Boolean,
            default: false
        },
        circle: {
            type: Boolean,
            default: false
        },
    }

}
</script>

App.vue

    <w-button round type="primary">点击</w-button>
    <w-button circle type="primary"></w-button>

样式 以primary为例

 .w-button--primary.is-round {
    border-radius: 20px;
    padding: 12px 23px;
 }
 .w-button--primary.is-circle {
    border-radius: 50%;
    padding: 12px;
 }

展示效果如下

image.png

icon属性

图标我这里使用的是iconfont里的字体图标,将iconfont网站下载来的解压包里的文件拷贝(其他文件不要,只要icon文件下的这些就好):

image.png

main.ts中引入文件到全局

import './assets/icon/iconfont.css';

w-button.vue中添加icon标签

<template>
    <button class="w-button" :class="[`w-button--${type}`,
     {'is-plain':plain},
     {'is-round':round},
     {'is-circle':circle}
    ]">
    <span v-show="icon" :class="['iconfont',icon]"></span>
    <span>
        <slot></slot>
    </span>
    </button>
</template>

<script lang="ts">
export default {
    name:"WButton",
    props: {
        type: {
            type: String,
            default: 'default'
        },
        plain: {
            type: Boolean,
            default: false
        },
        round: {
            type: Boolean,
            default: false
        },
        circle: {
            type: Boolean,
            default: false
        },
        icon: {
            type: String,
            default: ''
        }
    }

}
</script>

App.vue中使用

<w-button circle icon="icon-shanchu" type="primary"></w-button>

效果如下:

image.png

disabled属性

禁用属性可以让按钮失去点击功能,分两方面(功能,样式)。功能方面button标签加disabled属性,props校验。

<template>
    <button :disabled='disabled' class="w-button" :class="[`w-button--${type}`,
     {'is-plain':plain},
     {'is-round':round},
     {'is-circle':circle},
     {'is-disabled':disabled}
    ]">
    <span v-show="icon" :class="['iconfont',icon]"></span>
    <span>
        <slot></slot>
    </span>
    </button>
</template>

<script lang="ts">
export default {
    name:"WButton",
    props: {
        type: {
            type: String,
            default: 'default'
        },
        plain: {
            type: Boolean,
            default: false
        },
        round: {
            type: Boolean,
            default: false
        },
        circle: {
            type: Boolean,
            default: false
        },
        icon: {
            type: String,
            default: ''
        },
        disabled: {
            type: Boolean,
            default: false
        }
    }

}
</script>

样式方面(cursor 手型)

.w-button--primary.is-disabled {
    color: #fff;
    background-color: #a0cfff;
    border-color: #a0cfff;
    cursor: not-allowed;
    background-image: none;
 }

效果

image.png

未完