使用场景与最佳实践
Lerna Web UI 组件库专为各种前端应用场景设计,从简单的单页应用到复杂的企业级系统都能胜任。以下是详细的使用场景和最佳实践指南。
🎯 适用场景
1. 中后台管理系统
适用于企业级后台、Admin Dashboard、数据管理平台等。
典型特征
- 大量表单输入和数据录入
- 复杂的表格和列表展示
- 多变的交互状态(加载、禁用、错误等)
- 需要统一的设计规范和主题定制
示例:用户管理表单
<template>
<div class="user-form">
<h2>用户信息</h2>
<div class="form-item">
<label>用户名</label>
<Input
v-model="username"
placeholder="请输入用户名"
size="large"
/>
</div>
<div class="form-item">
<label>邮箱</label>
<Input
v-model="email"
type="email"
placeholder="请输入邮箱"
:error="!isValidEmail"
/>
</div>
<div class="form-actions">
<Button
type="primary"
size="large"
@click="handleSubmit"
:loading="isSubmitting"
>
提交
</Button>
<Button
size="large"
@click="handleReset"
>
重置
</Button>
</div>
</div>
</template>
<script setup lang="ts">
import { ref, computed } from 'vue'
import { Button, Input } from '@lerna-web-ui/ui'
const username = ref('')
const email = ref('')
const isSubmitting = ref(false)
const isValidEmail = computed(() => {
return !email.value || /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email.value)
})
const handleSubmit = async () => {
if (!isValidEmail.value) return
isSubmitting.value = true
try {
// 模拟 API 调用
await new Promise(resolve => setTimeout(resolve, 2000))
console.log('提交成功', { username: username.value, email: email.value })
} finally {
isSubmitting.value = false
}
}
const handleReset = () => {
username.value = ''
email.value = ''
}
</script>
<style scoped>
.user-form {
max-width: 500px;
padding: 24px;
}
.form-item {
margin-bottom: 16px;
}
.form-item label {
display: block;
margin-bottom: 8px;
font-weight: 500;
}
.form-actions {
display: flex;
gap: 12px;
margin-top: 24px;
}
</style>2. 数据可视化仪表板
适用于数据分析平台、监控面板、业务报表等。
示例:数据筛选工具栏
<template>
<div class="dashboard-toolbar">
<div class="filters">
<Input
v-model="searchQuery"
placeholder="搜索..."
size="small"
/>
<Button
type="primary"
size="small"
@click="handleSearch"
>
搜索
</Button>
<Button
size="small"
@click="handleExport"
>
导出
</Button>
</div>
<div class="actions">
<Button
type="success"
size="small"
@click="handleRefresh"
>
刷新
</Button>
</div>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { Button, Input } from '@lerna-web-ui/ui'
const searchQuery = ref('')
const handleSearch = () => {
console.log('搜索:', searchQuery.value)
}
const handleExport = () => {
console.log('导出数据')
}
const handleRefresh = () => {
console.log('刷新数据')
}
</script>
<style scoped>
.dashboard-toolbar {
display: flex;
justify-content: space-between;
align-items: center;
padding: 16px;
background: var(--lerna-bg-color-secondary);
border-radius: var(--lerna-radius-md);
margin-bottom: 24px;
}
.filters {
display: flex;
gap: 12px;
align-items: center;
}
.actions {
display: flex;
gap: 8px;
}
</style>3. 电商应用
适用于商品管理、订单处理、购物车等场景。
示例:商品操作按钮组
<template>
<div class="product-actions">
<Button
type="primary"
block
@click="addToCart"
>
加入购物车
</Button>
<div class="action-row">
<Button
type="danger"
size="small"
@click="buyNow"
>
立即购买
</Button>
<Button
size="small"
@click="addToWishlist"
>
<template #icon>❤️</template>
收藏
</Button>
</div>
</div>
</template>
<script setup lang="ts">
import { Button } from '@lerna-web-ui/ui'
const addToCart = () => {
console.log('加入购物车')
}
const buyNow = () => {
console.log('立即购买')
}
const addToWishlist = () => {
console.log('添加到收藏夹')
}
</script>
<style scoped>
.product-actions {
display: flex;
flex-direction: column;
gap: 12px;
}
.action-row {
display: flex;
gap: 8px;
}
</style>4. SaaS 应用
适用于订阅管理、设置页面、用户配置等。
示例:设置页面表单
<template>
<div class="settings-panel">
<section class="settings-section">
<h3>账户设置</h3>
<div class="setting-item">
<label>显示名称</label>
<Input
v-model="displayName"
placeholder="您的显示名称"
/>
</div>
<div class="setting-item">
<label>通知邮箱</label>
<Input
v-model="notificationEmail"
type="email"
placeholder="接收通知的邮箱地址"
/>
</div>
<div class="setting-actions">
<Button
type="primary"
@click="saveSettings"
>
保存设置
</Button>
<Button
@click="resetSettings"
>
重置
</Button>
</div>
</section>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { Button, Input } from '@lerna-web-ui/ui'
const displayName = ref('')
const notificationEmail = ref('')
const saveSettings = () => {
console.log('保存设置')
}
const resetSettings = () => {
displayName.value = ''
notificationEmail.value = ''
}
</script>
<style scoped>
.settings-panel {
max-width: 600px;
padding: 24px;
}
.settings-section {
margin-bottom: 32px;
}
.setting-item {
margin-bottom: 16px;
}
.setting-item label {
display: block;
margin-bottom: 8px;
font-weight: 500;
color: var(--lerna-text-color);
}
.setting-actions {
display: flex;
gap: 12px;
margin-top: 24px;
padding-top: 24px;
border-top: 1px solid var(--lerna-border-color);
}
</style>🔧 高级用法
1. 表单验证组合
结合多个组件实现完整的表单验证流程。
<template>
<form @submit.prevent="handleSubmit" class="validated-form">
<div class="form-field">
<label>用户名</label>
<Input
v-model="formData.username"
:error="errors.username"
placeholder="至少 3 个字符"
/>
<span v-if="errors.username" class="error-message">
{{ errors.username }}
</span>
</div>
<div class="form-field">
<label>密码</label>
<Input
v-model="formData.password"
type="password"
:error="errors.password"
placeholder="至少 6 个字符"
/>
<span v-if="errors.password" class="error-message">
{{ errors.password }}
</span>
</div>
<Button
type="primary"
type="submit"
:loading="isLoading"
:disabled="!canSubmit"
block
>
登录
</Button>
</form>
</template>
<script setup lang="ts">
import { ref, computed, reactive } from 'vue'
import { Button, Input } from '@lerna-web-ui/ui'
const formData = reactive({
username: '',
password: ''
})
const errors = reactive({
username: '',
password: ''
})
const isLoading = ref(false)
const canSubmit = computed(() => {
return formData.username.length >= 3 &&
formData.password.length >= 6
})
const validate = () => {
errors.username = ''
errors.password = ''
if (formData.username.length < 3) {
errors.username = '用户名至少 3 个字符'
return false
}
if (formData.password.length < 6) {
errors.password = '密码至少 6 个字符'
return false
}
return true
}
const handleSubmit = async () => {
if (!validate()) return
isLoading.value = true
try {
// 模拟 API 调用
await new Promise(resolve => setTimeout(resolve, 1500))
console.log('登录成功')
} finally {
isLoading.value = false
}
}
</script>
<style scoped>
.validated-form {
max-width: 400px;
}
.form-field {
margin-bottom: 16px;
}
.form-field label {
display: block;
margin-bottom: 8px;
font-weight: 500;
}
.error-message {
display: block;
margin-top: 4px;
color: var(--lerna-color-danger);
font-size: var(--lerna-font-size-sm);
}
</style>2. 响应式布局
适配不同屏幕尺寸的响应式设计。
<template>
<div class="responsive-container">
<div class="toolbar">
<Input
v-model="search"
placeholder="搜索内容..."
class="search-input"
/>
<div class="button-group">
<Button
type="primary"
size="small"
@click="handleAction1"
>
操作 1
</Button>
<Button
size="small"
@click="handleAction2"
>
操作 2
</Button>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { Button, Input } from '@lerna-web-ui/ui'
const search = ref('')
const handleAction1 = () => {
console.log('执行操作 1')
}
const handleAction2 = () => {
console.log('执行操作 2')
}
</script>
<style scoped>
.responsive-container {
width: 100%;
padding: 16px;
}
.toolbar {
display: flex;
gap: 16px;
align-items: center;
}
.search-input {
flex: 1;
min-width: 200px;
}
.button-group {
display: flex;
gap: 8px;
}
/* 移动端适配 */
@media (max-width: 768px) {
.toolbar {
flex-direction: column;
align-items: stretch;
}
.search-input {
width: 100%;
}
.button-group {
justify-content: stretch;
}
.button-group button {
flex: 1;
}
}
</style>
## 📊 性能优化
### 1. 按需加载与 Tree Shaking
组件库支持 Tree Shaking,建议直接导入需要的组件:
```ts
// ✅ 推荐:按需导入
import { Button, Input } from '@lerna-web-ui/ui'
// ❌ 不推荐:全量导入
import LernaWebUI from '@lerna-web-ui/ui'如果使用 Vite,可以配置 optimizeDeps 优化依赖预构建:
ts
// vite.config.ts
import { defineConfig } from 'vite'
export default defineConfig({
optimizeDeps: {
include: ['@lerna-web-ui/ui']
},
build: {
rollupOptions: {
output: {
manualChunks: {
'lerna-web-ui': ['@lerna-web-ui/ui']
}
}
}
}
})2. 自动导入配置(可选)
如果需要实现组件自动导入,可以手动配置解析器:
ts
// vite.config.ts
import { defineConfig } from 'vite'
import Components from 'unplugin-vue-components/vite'
export default defineConfig({
plugins: [
Components({
// 自定义解析器
resolvers: [
(name) => {
if (name === 'Button' || name === 'Input') {
return {
name,
from: '@lerna-web-ui/ui'
}
}
}
]
})
]
})3. 懒加载组件
对于大型应用,可以按需异步加载组件以优化初始加载性能:
``vue
```注意: 懒加载会增加组件的首次渲染时间,建议仅用于不常用的大型组件。
🎨 设计原则
1. 一致性
保持整个应用的视觉和交互体验一致。
vue
<template>
<!-- ✅ 好的做法:统一的按钮类型和尺寸 -->
<div class="button-group">
<Button type="primary" size="medium">主要操作</Button>
<Button size="medium">次要操作</Button>
</div>
<!-- ❌ 避免:混用不同的尺寸和类型 -->
<div class="button-group">
<Button type="primary" size="small">小按钮</Button>
<Button type="danger" size="large">大按钮</Button>
</div>
</template>2. 可访问性
确保所有用户都能使用你的应用。
vue
<template>
<!-- 为图标按钮添加 aria-label -->
<Button
size="small"
aria-label="关闭对话框"
@click="closeDialog"
>
✕
</Button>
<!-- 为表单字段添加关联标签 -->
<label for="username">用户名</label>
<Input id="username" v-model="username" />
</template>3. 状态反馈
及时响应用户操作,提供清晰的反馈。
vue
<template>
<Button
type="primary"
:loading="isLoading"
:disabled="isDisabled"
@click="handleAction"
>
{{ buttonText }}
</Button>
</template>
<script setup lang="ts">
import { computed } from 'vue'
const isLoading = ref(false)
const isSuccess = ref(false)
const buttonText = computed(() => {
if (isLoading.value) return '处理中...'
if (isSuccess.value) return '已完成'
return '提交'
})
</script>🚀 最佳实践总结
✅ 推荐做法
- 统一尺寸: 在同一界面中使用一致的按钮尺寸
- 明确状态: 清晰表达加载、禁用、错误等状态
- 语义化类型: 根据操作性质选择合适的按钮类型
- 适度使用: 避免过度装饰,保持简洁
- 测试验证: 在不同设备和主题下测试组件表现
❌ 避免事项
- 混用风格: 不要在同一区域混用多种按钮类型
- 忽略状态: 不要忘记处理加载和禁用状态
- 过度嵌套: 避免过多的条件渲染和嵌套
- 忽视无障碍: 不要忽略 ARIA 属性和键盘导航
- 硬编码样式: 优先使用设计令牌而非固定值
📚 相关资源
💡 提示: 以上示例代码可以直接复制使用,建议根据实际业务需求进行调整和优化。
