一.使用create vue 创建项目
这是搭建出来的默认界面,和使用vite的不一样
二.定义类型
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中:可以看到自定义的名字、属性
三.对外暴露出组件的一些属性
使用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);
}