1. Button 组件
<template>
<button class="btn" @click="onClick">
<slot></slot>
</button>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
export default defineComponent({
name: 'Button',
methods: {
onClick() {
this.$emit('click');
},
},
});
</script>
<style scoped>
.btn {
}
</style>
2. Input 组件
<template>
<input class="input" :value="value" @input="onInput" />
</template>
<script lang="ts">
import { defineComponent } from 'vue';
export default defineComponent({
name: 'Input',
props: {
value: {
type: String,
required: true,
},
},
methods: {
onInput(event: InputEvent) {
this.$emit('input', (event.target as HTMLInputElement).value);
},
},
});
</script>
<style scoped>
.input {
}
</style>
3. Checkbox 组件
<template>
<label class="checkbox">
<input type="checkbox" :checked="checked" @change="onChange" />
<span class="checkmark"></span>
<slot></slot>
</label>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
export default defineComponent({
name: 'Checkbox',
props: {
checked: {
type: Boolean,
default: false,
},
},
methods: {
onChange(event: InputEvent) {
this.$emit('change', (event.target as HTMLInputElement).checked);
},
},
});
</script>
<style scoped>
.checkbox {
}
.checkmark {
}
</style>
4. Radio 组件
<template>
<label class="radio">
<input type="radio" :value="value" v-model="modelValue" @change="onChange" />
<span class="radiomark"></span>
<slot></slot>
</label>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
export default defineComponent({
name: 'Radio',
props: {
value: {
type: String,
required: true,
},
modelValue: {
type: String,
required: true,
},
},
methods: {
onChange(event: InputEvent) {
this.$emit('change', (event.target as HTMLInputElement).value);
},
},
});
</script>
<style scoped>
.radio {
}
.radiomark {
}
</style>
5. Select 组件
<template>
<select class="select" v-model="modelValue" @change="onChange">
<option v-for="option in options" :value="option.value" :key="option.value">{{ option.label }}</option>
</select>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
export default defineComponent({
name: 'Select',
props: {
options: {
type: Array,
required: true,
},
modelValue: {
type: String,
required: true,
},
},
methods: {
onChange(event: InputEvent) {
this.$emit('change', (event.target as HTMLInputElement).value);
},
},
});
</script>
<style scoped>
.select {
}
</style>
6. Tabs 组件
<template>
<div class="tabs">
<div class="tab" v-for="tab in tabs" :key="tab.id" :class="{ active: tab.id === activeTab }" @click="activateTab(tab.id)">
tab.label }}
</div>
<div class="tab-content">
<slot></slot>
</div>
</div>
</template>
<script lang="ts">
import { defineComponent, ref } from 'vue';
export default defineComponent({
name: 'Tabs',
props: {
tabs: {
type: Array,
required: true,
},
},
setup() {
const activeTab = ref('');
const activateTab = (tabId: string) => {
activeTab.value = tabId;
};
return {
activeTab,
activateTab,
};
},
});
</script>
<style scoped>
.tabs {
}
.tab {
}
.tab.active {
}
.tab-content {
}
</style>
7. Modal 组件
<template>
<div class="modal" v-show="visible">
<div class="modal-content">
<slot></slot>
</div>
</div>
</template>
<script lang="ts">
import { defineComponent, ref } from 'vue';
export default defineComponent({
name: 'Modal',
props: {
visible: {
type: Boolean,
default: false,
},
},
});
</script>
<style scoped>
.modal {
}
.modal-content {
}
</style>
8. Pagination 组件
<template>
<ul class="pagination">
<li v-for="page in pageCount" :key="page" :class="{ active: page === currentPage }" @click="changePage(page)">
{{ page }}
</li>
</ul>
</template>
<script lang="ts">
import { defineComponent, ref } from 'vue';
export default defineComponent({
name: 'Pagination',
props: {
pageCount: {
type: Number,
required: true,
},
currentPage: {
type: Number,
required: true,
},
},
methods: {
changePage(page: number) {
this.$emit('page-change', page);
},
},
});
</script>
<style scoped>
.pagination {
}
.pagination li {
}
.pagination li.active {
}
</style>
9. Toast 组件
<template>
<div class="toast" v-show="visible">
{{ message }}
</div>
</template>
<script lang="ts">
import { defineComponent, ref } from 'vue';
export default defineComponent({
name: 'Toast',
props: {
message: {
type: String,
required: true,
},
visible: {
type: Boolean,
default: false,
},
},
});
</script>
<style scoped>
.toast {
}
</style>
10. Dropdown 组件
<template>
<div class="dropdown" @click="toggleDropdown">
<slot name="trigger"></slot>
<div class="dropdown-menu" v-show="isOpen">
<slot></slot>
</div>
</div>
</template>
<script lang="ts">
import { defineComponent, ref } from 'vue';
export default defineComponent({
name: 'Dropdown',
setup() {
const isOpen = ref(false);
const toggleDropdown = () => {
isOpen.value = !isOpen.value;
};
return {
isOpen,
toggleDropdown,
};
},
});
</script>
<style scoped>
.dropdown {
}
.dropdown-menu {
}
</style>
11. Carousel 组件
<template>
<div class="carousel">
<div class="carousel-inner">
<slot></slot>
</div>
<div class="carousel-controls">
<button class="prev" @click="prevSlide">Prev</button>
<button class="next" @click="nextSlide">Next</button>
</div>
</div>
</template>
<script lang="ts">
import { defineComponent, ref } from 'vue';
export default defineComponent({
name: 'Carousel',
methods: {
prevSlide() {
this.$emit('prev-slide');
},
nextSlide() {
this.$emit('next-slide');
},
},
});
</script>
<style scoped>
.carousel {
}
.carousel-inner {
}
.carousel-controls {
}
.carousel-controls button {
}
</style>
12. Accordion 组件
<template>
<div class="accordion">
<div class="accordion-item" v-for="item in items" :key="item.id">
<div class="accordion-header" @click="toggleItem(item.id)">
{{ item.title }}
</div>
<div class="accordion-content" v-show="item.id === activeItem">
{{ item.content }}
</div>
</div>
</div>
</template>
<script lang="ts">
import { defineComponent, ref } from 'vue';
export default defineComponent({
name: 'Accordion',
props: {
items: {
type: Array,
required: true,
},
},
setup() {
const activeItem = ref('');
const toggleItem = (itemId: string) => {
activeItem.value = activeItem.value === itemId ? '' : itemId;
};
return {
activeItem,
toggleItem,
};
},
});
</script>
<style scoped>
.accordion {
}
.accordion-item {
}
.accordion-header {
}
.accordion-content {
}
</style>
13. Datepicker 组件
<template>
<input class="datepicker" :value="value" @input="onInput" />
</template>
<script lang="ts">
import { defineComponent } from 'vue';
export default defineComponent({
name: 'Datepicker',
props: {
value: {
type: String,
required: true,
},
},
methods: {
onInput(event: InputEvent) {
this.$emit('input', (event.target as HTMLInputElement).value);
},
},
});
</script>
<style scoped>
.datepicker {
}
</style>
14. Table 组件
<template>
<table class="table">
<thead>
<tr>
<th v-for="column in columns" :key="column.field">{{ column.label }}</th>
</tr>
</thead>
<tbody>
<tr v-for="row in rows" :key="row.id">
<td v-for="column in columns" :key="column.field">{{ row[column.field] }}</td>
</tr>
</tbody>
</table>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
export default defineComponent({
name: 'Table',
props: {
columns: {
type: Array,
required: true,
},
rows: {
type: Array,
required: true,
},
},
});
</script>
<style scoped>
.table {
}
.table th {
}
.table td {
}
</style>
15. Slider 组件
<template>
<div class="slider">
<div class="slider-bar">
<div class="slider-handle" :style="{ left: handlePosition + '%' }" @mousedown="startDragging" @touchstart="startDragging"></div>
</div>
</div>
</template>
<script lang="ts">
import { defineComponent, ref } from 'vue';
export default defineComponent({
name: 'Slider',
setup() {
const handlePosition = ref(0);
const isDragging = ref(false);
const startDragging = () => {
isDragging.value = true;
};
return {
handlePosition,
startDragging,
};
},
});
</script>
<style scoped>
.slider {
}
.slider-bar {
}
.slider-handle {
}
</style>
16. Progress 组件
<template>
<div class="progress">
<div class="progress-bar" :style="{ width: progress + '%' }"></div>
</div>
</template>
<script lang="ts">
import { defineComponent, ref } from 'vue';
export default defineComponent({
name: 'Progress',
props: {
progress: {
type: Number,
required: true,
},
},
});
</script>
<style scoped>
.progress {
}
.progress-bar {
}
</style>
17. Tooltip 组件
<template>
<div class="tooltip" @mouseenter="showTooltip" @mouseleave="hideTooltip">
<slot></slot>
<div class="tooltip-content" v-show="isTooltipVisible">{{ content }}</div>
</div>
</template>
<script lang="ts">
import { defineComponent, ref } from 'vue';
export default defineComponent({
name: 'Tooltip',
props: {
content: {
type: String,
required: true,
},
},
setup() {
const isTooltipVisible = ref(false);
const showTooltip = () => {
isTooltipVisible.value = true;
};
const hideTooltip = () => {
isTooltipVisible.value = false;
};
return {
isTooltipVisible,
showTooltip,
hideTooltip,
};
},
});
</script>
<style scoped>
.tooltip {
}
.tooltip-content {
}
</style>
18. Card 组件
<template>
<div class="card">
<div class="card-header">
<slot name="header"></slot>
</div>
<div class="card-body">
<slot></slot>
</div>
<div class="card-footer">
<slot name="footer"></slot>
</div>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
export default defineComponent({
name: 'Card',
});
</script>
<style scoped>
.card {
}
.card-header {
}
.card-body {
}
.card-footer {
}
</style>
19. Alert 组件
<template>
<div class="alert" :class="type">
<slot></slot>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
export default defineComponent({
name: 'Alert',
props: {
type: {
type: String,
default: 'info',
},
},
});
</script>
<style scoped>
.alert {
}
.alert.info {
}
.alert.warning {
}
.alert.error {
}
</style>
20. Navbar 组件
<template>
<nav class="navbar">
<ul class="navbar-nav">
<li class="nav-item" v-for="item in items" :key="item.id">
<a :href="item.url" :class="{ active: item.url === activeItem }">{{ item.label }}</a>
</li>
</ul>
</nav>
</template>
<script lang="ts">
import { defineComponent, ref } from 'vue';
export default defineComponent({
name: 'Navbar',
props: {
items: {
type: Array,
required: true,
},
activeItem: {
type: String,
required: true,
},
},
});
</script>
<style scoped>
.navbar {
}
.navbar-nav {
}
.nav-item {
}
.nav-item a {
}
.nav-item a.active {
}
</style>