@tplc/business
Version:
323 lines (267 loc) • 8.44 kB
Markdown
# lcb-empty 组件实现总结
## 🎯 实现目标
将 empty 状态从 `lcb-product` 中抽离成独立的 `lcb-empty` 组件,实现在多个组件中复用。
## ✅ 已完成的工作
### 1. 创建独立组件
#### 新增文件
- `packages/business/components/lcb-empty/lcb-empty.vue` - 组件实现
- `packages/business/components/lcb-empty/types.ts` - 类型定义
- `packages/business/components/lcb-empty/README.md` - 使用文档
#### 组件特性
- ✅ 支持自定义图片和文字
- ✅ 支持自定义图片尺寸(imageWidth、imageHeight)
- ✅ 支持自定义文字样式(textColor、textSize、textWeight)
- ✅ 支持自定义图片与文字间距(gap)
- ✅ 支持自定义最小高度(minHeight)
- ✅ 支持自定义内边距(paddingTop/Right/Bottom/Left)
- ✅ 响应式设计,使用 rpx 单位
- ✅ 图片和文字可独立显示/隐藏
### 2. 更新相关组件
#### lcb-product
**修改文件:**
- `types.ts` - 导入 `LcbEmptyProps`,替换原有 `EmptyProps`
- `lcb-product.vue` - 使用 `<lcb-empty>` 组件替换原有实现
**实现逻辑:**
```typescript
// 计算是否显示空状态
const showEmpty = computed(() => {
return !loading.value && renderList.value.length === 0
})
// 合并配置(自动继承父组件的内边距)
const mergedEmptyProps = computed(() => {
return {
...props.emptyProps,
paddingTop: props.emptyProps?.paddingTop ?? props.paddingVertical ?? 0,
paddingRight: props.emptyProps?.paddingRight ?? props.paddingHorizontal ?? 0,
paddingBottom: props.emptyProps?.paddingBottom ?? props.paddingVertical ?? 0,
paddingLeft: props.emptyProps?.paddingLeft ?? props.paddingHorizontal ?? 0,
}
})
```
#### lcb-list
**修改文件:**
- `types.ts` - 导入 `LcbEmptyProps`,更新类型引用
**实现方式:**
- 通过 props 将 `emptyProps` 透传给内部的 `lcb-product` 组件
#### lcb-wrapper-list (新增支持)
**修改文件:**
- `types.ts` - 导入 `LcbEmptyProps`,添加 `emptyProps` 属性
- `lcb-wrapper-list.vue` - 添加空状态显示逻辑
**实现逻辑:**
```typescript
// 计算是否显示空状态
const showEmpty = computed(() => {
return renderList.value.length === 0
})
// 合并配置
const mergedEmptyProps = computed(() => {
return {
...props.emptyProps,
paddingTop: props.emptyProps?.paddingTop ?? props.paddingVertical ?? 0,
paddingRight: props.emptyProps?.paddingRight ?? props.paddingHorizontal ?? 0,
paddingBottom: props.emptyProps?.paddingBottom ?? props.paddingVertical ?? 0,
paddingLeft: props.emptyProps?.paddingLeft ?? props.paddingHorizontal ?? 0,
}
})
```
### 3. 更新文档
#### 组件文档
- `lcb-empty/README.md` - 详细的组件使用文档
#### 综合文档
- `EMPTY_STATE_README.md` - 更新为包含 lcb-empty 独立组件的说明
- `CHANGELOG_EMPTY.md` - 更新为包含组件抽离的变更记录
- `EMPTY_USAGE.md` - 保持不变(原有使用文档)
- `EMPTY_IMPLEMENTATION.md` - 保持不变(原有实现文档)
- `EMPTY_QUICK_REF.md` - 保持不变(原有快速参考)
### 4. 示例页面
#### 新增示例
- `packages/engine/src/pages/lcb-wrapper-list/empty-demo.vue` - lcb-wrapper-list 使用示例
#### 已有示例
- `packages/engine/src/pages/lcb-product/empty-demo.vue` - lcb-product 使用示例(保持不变)
## 📊 类型定义
### LcbEmptyProps
```typescript
export interface LcbEmptyProps {
/** 空状态图片地址 */
image?: string
/** 空状态文字 */
text?: string
/** 图片宽度(rpx) */
imageWidth?: number
/** 图片高度(rpx) */
imageHeight?: number
/** 文字颜色 */
textColor?: string
/** 文字大小(rpx) */
textSize?: number
/** 文字粗细 */
textWeight?: 'normal' | 'bold' | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900
/** 图片与文字的间距(rpx) */
gap?: number
/** 最小高度(rpx) */
minHeight?: number
/** 内边距 - 上(rpx) */
paddingTop?: number
/** 内边距 - 右(rpx) */
paddingRight?: number
/** 内边距 - 下(rpx) */
paddingBottom?: number
/** 内边距 - 左(rpx) */
paddingLeft?: number
}
```
### 默认值
```typescript
{
text: '暂无数据',
imageWidth: 400,
imageHeight: 400,
textColor: '#999999',
textSize: 28,
textWeight: 'normal',
gap: 24,
minHeight: 400,
paddingTop: 0,
paddingRight: 0,
paddingBottom: 0,
paddingLeft: 0,
}
```
## 🎨 使用方式
### 1. 直接使用 lcb-empty
```vue
<template>
<lcb-empty
image="/static/empty.png"
text="暂无数据"
:imageWidth="500"
:imageHeight="500"
/>
</template>
```
### 2. 在 lcb-product 中使用
```vue
<template>
<lcb-product
:items="[]"
:emptyProps="{
image: '/static/empty.png',
text: '还没有点亮记录',
}"
/>
</template>
```
### 3. 在 lcb-list 中使用
```vue
<template>
<lcb-list
pageFilterType="product-filter"
:emptyProps="{
image: '/static/empty.png',
text: '还没有点亮记录',
}"
/>
</template>
```
### 4. 在 lcb-wrapper-list 中使用
```vue
<template>
<lcb-wrapper-list
:dataSource="dataSource"
:emptyProps="{
image: '/static/empty.png',
text: '暂无数据',
}"
>
<template #default="{ data }">
<view>{{ data }}</view>
</template>
</lcb-wrapper-list>
</template>
```
## 🔧 技术实现
### 组件结构
```
lcb-empty
├── template
│ └── view.lcb-empty
│ ├── wd-img (图片)
│ └── view.lcb-empty__text (文字)
├── script
│ ├── props 定义
│ ├── transformValueUnit 工具函数
│ └── defineExpose
└── style
└── scoped styles
```
### 自动注册
组件通过 `packages/business/index.ts` 中的 glob 导入自动注册:
```typescript
const importFn = import.meta.glob('./components/lcb-*/lcb-*.vue', { eager: true })
```
### 内边距继承
在父组件中,空状态的内边距会自动继承父组件的 `paddingVertical` 和 `paddingHorizontal` 设置:
```typescript
const mergedEmptyProps = computed(() => {
return {
...props.emptyProps,
paddingTop: props.emptyProps?.paddingTop ?? props.paddingVertical ?? 0,
paddingRight: props.emptyProps?.paddingRight ?? props.paddingHorizontal ?? 0,
paddingBottom: props.emptyProps?.paddingBottom ?? props.paddingVertical ?? 0,
paddingLeft: props.emptyProps?.paddingLeft ?? props.paddingHorizontal ?? 0,
}
})
```
## ✅ 验证结果
- ✅ TypeScript 类型检查通过
- ✅ 无 Linter 错误
- ✅ 组件可以独立使用
- ✅ 在 lcb-product 中正常工作
- ✅ 在 lcb-list 中正常工作
- ✅ 在 lcb-wrapper-list 中正常工作
- ✅ 向下兼容,不影响现有功能
- ✅ 文档完整
## 🎉 优势
1. **代码复用** - 一个组件,多处使用
2. **易于维护** - 修改只需在一个地方进行
3. **独立使用** - 可以在任何地方单独使用 lcb-empty
4. **类型安全** - 完整的 TypeScript 支持
5. **灵活配置** - 支持继承父组件配置,也可以完全自定义
6. **文档完善** - 多份文档覆盖不同使用场景
## 📁 文件清单
### 新增文件
```
packages/business/components/
├── lcb-empty/
│ ├── lcb-empty.vue (新增)
│ ├── types.ts (新增)
│ ├── README.md (新增)
│ └── IMPLEMENTATION_SUMMARY.md (新增)
└── packages/engine/src/pages/
└── lcb-wrapper-list/
└── empty-demo.vue (新增)
```
### 修改文件
```
packages/business/components/
├── lcb-product/
│ ├── lcb-product.vue (修改)
│ └── types.ts (修改)
├── lcb-list/
│ └── types.ts (修改)
├── lcb-wrapper-list/
│ ├── lcb-wrapper-list.vue (修改)
│ └── types.ts (修改)
├── EMPTY_STATE_README.md (更新)
└── CHANGELOG_EMPTY.md (更新)
```
## 🎯 适用组件
- ✅ lcb-empty (独立组件)
- ✅ lcb-product
- ✅ lcb-list
- ✅ lcb-wrapper-list
- 🔄 可扩展到其他需要空状态的组件
---
**实现时间**: 2026-01-19
**版本**: v2.0.0 (组件抽离版本)
**状态**: ✅ 已完成并测试通过