Skip to content

公共组件

概述

公共组件是 Web Boot 项目中的通用组件库,提供了一系列可复用的 UI 组件,支持跨框架使用。

特性

  • 🎯 跨框架支持 - 基于 Web Components,支持 Vue、React、Svelte 等框架
  • 🎨 统一设计 - 遵循统一的设计规范和交互模式
  • 🔧 高度可配置 - 支持多种配置选项和自定义样式
  • 📱 响应式设计 - 完美适配各种屏幕尺寸
  • 🎨 主题定制 - 支持明暗主题切换和自定义主题
  • 🌐 国际化 - 支持多语言切换
  • 无障碍支持 - 符合 WCAG 2.1 标准

安装

bash
# 安装组件库
pnpm add @web-boot/common-components

组件列表

Language 组件

多语言切换组件,支持动态切换应用语言。

基础用法

vue
<template>
	<language-selector :languages="languages" :current-locale="currentLocale" @change="handleLanguageChange" />
</template>

<script setup lang="ts">
	import { ref } from 'vue'
	import 'language-selector'

	const currentLocale = ref('zh-CN')

	const languages = [
		{ code: 'zh-CN', name: '中文', flag: '🇨🇳' },
		{ code: 'en-US', name: 'English', flag: '🇺🇸' },
		{ code: 'ja-JP', name: '日本語', flag: '🇯🇵' },
	]

	const handleLanguageChange = (locale: string) => {
		currentLocale.value = locale
		// 切换语言逻辑
	}
</script>

属性配置

属性名类型默认值说明
languagesLanguage[][]支持的语言列表
current-localestring'zh-CN'当前语言
show-flagbooleantrue是否显示国旗图标
show-namebooleantrue是否显示语言名称
positionstring'bottom'下拉菜单位置

事件

事件名参数说明
change(locale: string)语言切换事件

Theme 组件

主题切换组件,支持明暗主题切换。

基础用法

vue
<template>
	<theme-switcher :current-theme="currentTheme" :themes="themes" @change="handleThemeChange" />
</template>

<script setup lang="ts">
	import { ref } from 'vue'
	import 'theme-switcher'

	const currentTheme = ref('light')

	const themes = [
		{ value: 'light', label: '浅色', icon: 'sun' },
		{ value: 'dark', label: '深色', icon: 'moon' },
		{ value: 'auto', label: '自动', icon: 'auto' },
	]

	const handleThemeChange = (theme: string) => {
		currentTheme.value = theme
		// 切换主题逻辑
	}
</script>

属性配置

属性名类型默认值说明
current-themestring'light'当前主题
themesTheme[][]可用主题列表
show-iconbooleantrue是否显示图标
show-labelbooleantrue是否显示标签
animationbooleantrue是否启用切换动画

事件

事件名参数说明
change(theme: string)主题切换事件

高级用法

组合使用

vue
<template>
	<div class="header-actions">
		<language-selector :languages="languages" :current-locale="currentLocale" @change="handleLanguageChange" />

		<theme-switcher :current-theme="currentTheme" :themes="themes" @change="handleThemeChange" />
	</div>
</template>

<script setup lang="ts">
	import { ref } from 'vue'
	import 'language-selector'
	import 'theme-switcher'

	const currentLocale = ref('zh-CN')
	const currentTheme = ref('light')

	const languages = [
		{ code: 'zh-CN', name: '中文', flag: '🇨🇳' },
		{ code: 'en-US', name: 'English', flag: '🇺🇸' },
	]

	const themes = [
		{ value: 'light', label: '浅色', icon: 'sun' },
		{ value: 'dark', label: '深色', icon: 'moon' },
	]

	const handleLanguageChange = (locale: string) => {
		currentLocale.value = locale
		// 更新 i18n 配置
		i18n.global.locale.value = locale
	}

	const handleThemeChange = (theme: string) => {
		currentTheme.value = theme
		// 更新主题配置
		document.documentElement.setAttribute('data-theme', theme)
	}
</script>

<style scoped>
	.header-actions {
		display: flex;
		align-items: center;
		gap: 16px;
	}
</style>

自定义样式

vue
<template>
	<div class="custom-header">
		<language-selector
			:languages="languages"
			:current-locale="currentLocale"
			class="custom-language"
			@change="handleLanguageChange"
		/>

		<theme-switcher :current-theme="currentTheme" :themes="themes" class="custom-theme" @change="handleThemeChange" />
	</div>
</template>

<style scoped>
	.custom-header {
		display: flex;
		align-items: center;
		gap: 12px;
		padding: 8px 16px;
		background: var(--header-bg);
		border-bottom: 1px solid var(--border-color);
	}

	.custom-language {
		--selector-bg: var(--primary-color);
		--selector-text-color: white;
		--selector-border-radius: 6px;
	}

	.custom-theme {
		--switcher-bg: var(--secondary-bg);
		--switcher-text-color: var(--text-color);
		--switcher-border-radius: 8px;
	}
</style>

国际化集成

与 Vue I18n 集成

typescript
// i18n/index.ts
import { createI18n } from 'vue-i18n'
import zhCN from './locales/zh-CN'
import enUS from './locales/en-US'

const i18n = createI18n({
	legacy: false,
	locale: 'zh-CN',
	fallbackLocale: 'en-US',
	messages: {
		'zh-CN': zhCN,
		'en-US': enUS,
	},
})

export default i18n
vue
<template>
	<language-selector :languages="languages" :current-locale="currentLocale" @change="handleLanguageChange" />
</template>

<script setup lang="ts">
	import { ref } from 'vue'
	import { useI18n } from 'vue-i18n'

	const { locale } = useI18n()
	const currentLocale = ref(locale.value)

	const handleLanguageChange = (newLocale: string) => {
		currentLocale.value = newLocale
		locale.value = newLocale
		localStorage.setItem('locale', newLocale)
	}
</script>

与 React Intl 集成

tsx
import React, { useState } from 'react'
import { IntlProvider } from 'react-intl'
import 'language-selector'

const App: React.FC = () => {
	const [locale, setLocale] = useState('zh-CN')
	const [messages, setMessages] = useState(zhCN)

	const handleLanguageChange = async (newLocale: string) => {
		setLocale(newLocale)

		// 动态加载语言包
		const newMessages = await import(`./locales/${newLocale}`)
		setMessages(newMessages.default)
	}

	return (
		<IntlProvider locale={locale} messages={messages}>
			<language-selector languages={languages} current-locale={locale} onLanguageChange={handleLanguageChange} />
		</IntlProvider>
	)
}

主题系统集成

CSS 变量主题

css
/* themes/light.css */
:root {
	--primary-color: #409eff;
	--secondary-color: #67c23a;
	--text-color: #303133;
	--bg-color: #ffffff;
	--border-color: #dcdfe6;
}

/* themes/dark.css */
[data-theme='dark'] {
	--primary-color: #409eff;
	--secondary-color: #67c23a;
	--text-color: #ffffff;
	--bg-color: #1a1a1a;
	--border-color: #4c4c4c;
}
vue
<template>
	<theme-switcher :current-theme="currentTheme" :themes="themes" @change="handleThemeChange" />
</template>

<script setup lang="ts">
	import { ref, onMounted } from 'vue'

	const currentTheme = ref('light')

	const handleThemeChange = (theme: string) => {
		currentTheme.value = theme
		document.documentElement.setAttribute('data-theme', theme)
		localStorage.setItem('theme', theme)
	}

	onMounted(() => {
		// 恢复保存的主题
		const savedTheme = localStorage.getItem('theme') || 'light'
		currentTheme.value = savedTheme
		document.documentElement.setAttribute('data-theme', savedTheme)
	})
</script>

性能优化

懒加载

vue
<template>
	<Suspense>
		<template #default>
			<AsyncLanguageSelector />
		</template>
		<template #fallback>
			<div class="loading">加载中...</div>
		</template>
	</Suspense>
</template>

<script setup lang="ts">
	import { defineAsyncComponent } from 'vue'

	const AsyncLanguageSelector = defineAsyncComponent(() => import('language-selector'))
</script>

按需加载

typescript
// 按需导入组件
import { LanguageSelector, ThemeSwitcher } from '@web-boot/common-components'

// 注册组件
app.component('language-selector', LanguageSelector)
app.component('theme-switcher', ThemeSwitcher)

最佳实践

1. 组件配置

typescript
// 推荐:使用配置文件管理组件选项
const componentConfig = {
	language: {
		defaultLocale: 'zh-CN',
		supportedLocales: ['zh-CN', 'en-US', 'ja-JP'],
		fallbackLocale: 'en-US',
	},
	theme: {
		defaultTheme: 'light',
		supportedThemes: ['light', 'dark', 'auto'],
		storageKey: 'app-theme',
	},
}

2. 错误处理

vue
<template>
	<language-selector
		:languages="languages"
		:current-locale="currentLocale"
		@change="handleLanguageChange"
		@error="handleError"
	/>
</template>

<script setup lang="ts">
	const handleError = (error: Error) => {
		console.error('语言切换错误:', error)
		ElMessage.error('语言切换失败,请重试')
	}
</script>

3. 无障碍支持

vue
<template>
	<language-selector
		:languages="languages"
		:current-locale="currentLocale"
		aria-label="选择语言"
		role="combobox"
		@change="handleLanguageChange"
	/>
</template>

常见问题

1. 组件不显示

问题: 组件注册后不显示

解决方案:

vue
<template>
	<div>
		<language-selector />
	</div>
</template>

<script setup lang="ts">
	// 确保正确导入
	import 'language-selector'
</script>

2. 事件不触发

问题: 语言切换事件不触发

解决方案:

vue
<template>
	<language-selector @change="handleLanguageChange" />
</template>

<script setup lang="ts">
	const handleLanguageChange = (locale: string) => {
		console.log('语言切换:', locale)
		// 确保事件处理函数正确定义
	}
</script>

3. 样式不生效

问题: 自定义样式不生效

解决方案:

vue
<style scoped>
	/* 使用深度选择器 */
	:deep(.language-selector) {
		--selector-bg: #1890ff;
		--selector-text-color: white;
	}
</style>

更新日志

v1.0.0

  • 初始版本发布
  • 支持 Language 和 Theme 组件
  • 集成国际化支持
  • 支持主题切换功能

基于 MIT 许可发布