Button按钮组件

74 阅读3分钟

一.使用create vue 创建项目

image.png

这是搭建出来的默认界面,和使用vite的不一样

image.png

二.定义类型

types.ts

import type { PropType } from "vue";
export type ButtonType = 'primary' | 'success' | 'warning' | 'info'
export type ButtonSize = 'large' | 'small'

export interface ButtonProps {
    type?: ButtonType;
    size?: ButtonSize;
    plain?: boolean;
    round?: boolean;
    circle?: boolean;
    disabled?: boolean;
}

在Button.vue组件中引入类型:

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

<script setup lang="ts">
import type { ButtonProps } from "./types";
defineProps<ButtonProps>()
//组件名称
defineOptions({
    name: 'LytButton'
})
</script>

<style scoped></style>

在App.vue中使用组件:

<Button type="primary" disabled>test Button</Button>

在devtool中:可以看到自定义的名字、属性

image.png

三.对外暴露出组件的一些属性

使用ref、defineExpose()

Button.vue

<template>
    <button ref="_ref" class="lu-button" :class="{
        [`lu-button--${type}`]: type,
        [`lu-button--${size}`]: size,
        'is-plain': plain,
        'is-round': round,
        'is-circle': circle,
        'is-disabled': disabled,

    }" :disabled="disabled" :autofocus="autofocus" :type="nativeType">
        <span>
            <slot></slot>
        </span>
    </button>
</template>

<script setup lang="ts">
import type { ButtonProps } from "./types";
import { ref } from 'vue';
withDefaults(defineProps<ButtonProps>(), {
    nativeType: 'button'
})
//组件名称
defineOptions({
    name: 'LytButton'
})
//使用ref暴露出dom节点
const _ref = ref<HTMLButtonElement>()
defineExpose({
    ref: _ref
})
</script>

<style scoped></style>

App.vue:

<script setup lang="ts">
import Button from './components/Button/Button.vue'
import { ref, onMounted } from 'vue'
import { ButtonInstance } from './components/Button/types'
const buttonRef = ref<ButtonInstance | null>(null)
onMounted(() => {
  //拿到dom节点
  if (buttonRef.value)
    console.log('buttonRef', buttonRef.value.ref);
})
</script>

<template>

  <main>
    <Button type="primary" disabled ref="buttonRef">test Button</Button>
  </main>
</template>

<style scoped></style>

types.ts定义了ButtonInstance类型

export interface BUttonInstance {
    ref: HTMLButtonElement
}

四.选用postcss

css自定义变量的方式:

在style->index.css中:

:root {
    --main-bg-color: blue;
}

引入到main.ts中后,就可以在组件中使用这个变量了

Button.vue:

<style>
.lu-button {
    background-color: var(--main-bg-color);
}
</style>

五.添加色彩变量

var.css:

:root {
    --lu-color-white: #ffffff;
    --lu-color-black: #000000;
    --lu-color-primary: #409eff;
    --lu-color-primary-light-3: #79bbff;
    --lu-color-primary-light-5: #a0cfff;
    --lu-color-primary-light-7: #c6e2ff;
    --lu-color-primary-light-8: #d9ecff;
    --lu-color-primary-light-9: #ecf5ff;
    --lu-color-primary-dark-2: #337ecc;
    --lu-color-success: #67c23a;
    --lu-color-success-light-3: #495d47;
    --lu-color-success-light-5: #b3e19d;
    --lu-color-success-light-7: #d1e7d4;
    --lu-color-success-light-8: #e1f3d8;
    --lu-color-success-light-9: #f0f9eb;
    --lu-color-success-dark-2: #529b2e;
    --lu-color-warning: #e6a23c;
    --lu-color-warning-light-3: #eebe77;
    --lu-color-warning-light-5: #f3d19e;
    --lu-color-warning-light-7: #f8e3c5;
    --lu-color-warning-light-8: #faecdb;
    --lu-color-warning-light-9: #fdf6ec;
    --lu-color-danger: #f56c6c;
    --lu-color-danger-light-3: #f89898;
    --lu-color-danger-light-5: #fab6b6;
    --lu-color-danger-light-7: #fc3d3d;
    --lu-color-danger-light-8: #fde2e2;
    --lu-color-danger-light-9: #fef0f0;
    --lu-color-danger-dark-2: #c45656;
    --lu-color-info: #909399;
    --lu-color-info-light-3: #b1b3b8;
    --lu-color-info-light-5: #c8c9cc;
    --lu-color-info-light-7: #dedef0;
    --lu-color-info-light-8: #e9e9eb;
    --lu-color-info-light-9: #f4f4f5;
    --lu-color-info-dark-2: #737676;

    --lu-bg-color: #ffffff;
    --lu-bg-color-page: #f2f3f5;
    --lu-bg-color-overlay: #ffffff;
    --lu-text-color-primary: #303133;
    --lu-text-color-regular: #606266;
    --lu-text-color-secondary: #999999;
    --lu-text-color-placeholder: #aab2b9;
    --lu-text-color-disabled: #c0c4cc;
    --lu-border-color: #dcdfe6;
    --lu-border-color-light: #e4e7ed;
    --lu-border-color-lighter: #ebeef5;
    --lu-border-color-extra-light: #f2f6fc;
    --lu-border-color-dark: #d4d7de;
    --lu-border-color-darker: #cdd0d6;
    --lu-fill-color: #f0f2f5;
    --lu-fill-color-light: #f5f7fa;
    --lu-fill-color-lighter: #fafafa;
    --lu-fill-color-extra-light: #fafcff;
    --lu-fill-color-dark: #ebedf0;
    --lu-fill-color-darker: #e6e8eb;
    --lu-fill-color-blank: #ffffff;

    /* border */
    --lu-border-width: 1px;
    --lu-border-style: solid;
    --lu-border-color-hover: var(--lu-text-color-disabled);
    --lu-border: var(--lu-border-width) var(--lu-border-style) var(--lu-border-color);
    --lu-border-radius-base: 4px;
    --lu-border-radius-small: 2px;
    --lu-border-radius-round: 20px;
    --lu-border-radius-circle: 100%;

    /* font */
    --lu-font-size-extra-large: 20px;
    --lu-font-size-large: 18px;
    --lu-font-size-medium: 16px;
    --lu-font-size-base: 14px;
    --lu-font-size-small: 13px;
    --lu-font-size-extra-small: 12px;
    --lu-font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;
    --lu-font-weight-primary: 500;

    /* disabled */
    --lu-disabled-bg-color: var(--lu-fill-color-light);
    --lu-disabled-text-color: var(--lu-text-color-placeholder);
    --lu-disabled-border-color: var(--lu-border-color-light);
}

reset.css:

body {
    font-family: var(--lu-font-family);
    font-weight: 400;
    font-size: var(--lu-font-size-base);
    color: var(--lu-text-color-primary);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    -webkit-tap-highlight-color: transparent;
}

a {
    color: var(--lu-color-primary);
    text-decoration: none;
}

a:hover,
a:focus {
    color: var(--lu-color-primary-light-3);
}

a:active {
    color: var(--lu-color-primary-dark-2);
}