README.md 8.87 KB

Components 目录

本项目组件使用 Vue 3 Composition API + <script setup> 编写,按功能模块组织。


📚 目录结构

components/
├── cards/              # 卡片组件
├── documents/          # 文档预览组件
├── examples/           # 示例组件
├── forms/              # 表单组件
├── icons/              # 图标组件
├── list/               # 列表组件
├── navigation/         # 导航组件
└── plan/               # 计划书组件

📦 组件索引

导航组件 (navigation/)

组件 功能 Props
NavHeader 页面顶部导航栏 title, showBack, preventDefaultBack
TabBar 底部标签导航栏 current, tabs

使用示例

<template>
  <NavHeader title="页面标题" />
  <TabBar current="home" />
</template>

<script setup>
import NavHeader from '@/components/navigation/NavHeader.vue'
import TabBar from '@/components/navigation/TabBar.vue'
</script>

卡片组件 (cards/)

组件 功能 Props
MaterialCard 资料/文档卡片 title, icon, learners, docType, collected
ProductCard 产品卡片 name, type, tags, collected

使用示例

<template>
  <MaterialCard
    :title="item.title"
    :icon="item.icon"
    :learners="item.learners"
    :doc-type="item.docType"
    :collected="item.collected"
    @view="handleView"
  />
</template>

<script setup>
import MaterialCard from '@/components/cards/MaterialCard.vue'
</script>

表单组件 (forms/)

组件 功能 Props
SearchBar 搜索栏 modelValue, placeholder, disabled
FilterTabs 筛选标签 options, modelValue

使用示例

<template>
  <SearchBar v-model="searchText" placeholder="搜索资料" />
  <FilterTabs v-model="activeTab" :options="tabs" />
</template>

<script setup>
import SearchBar from '@/components/forms/SearchBar.vue'
import FilterTabs from '@/components/forms/FilterTabs.vue'
</script>

列表组件 (list/)

组件 功能 Props
SectionCard 分组卡片容器 title
SectionItem 分组列表项 title, subtitle, icon
LoadMoreList 加载更多列表 items, hasMore, loading
ListItemActions 列表项操作按钮 viewable, collectable, deletable

使用示例

<template>
  <SectionCard title="常用功能">
    <SectionItem
      v-for="item in items"
      :key="item.id"
      :title="item.title"
      :subtitle="item.subtitle"
      :icon="item.icon"
      @click="handleClick"
    />
  </SectionCard>

  <LoadMoreList
    :items="list"
    :hasMore="hasMore"
    :loading="loading"
    @load-more="loadMore"
  />
</template>

<script setup>
import SectionCard from '@/components/list/SectionCard.vue'
import SectionItem from '@/components/list/SectionItem.vue'
import LoadMoreList from '@/components/list/LoadMoreList/index.vue'
</script>

文档组件 (documents/)

组件 功能 Props
PdfPreview PDF 预览 url
OfficeViewer Office 文档查看器 url
DocumentPreview 通用文档预览 file

计划书组件 (plan/)

弹窗容器

组件 功能
PlanPopupNew 计划书弹窗容器
PlanFormContainer 计划书表单容器

表单字段 (PlanFields/)

组件 功能
NameInput 姓名输入
AgePickerGlobal 年龄选择器
DatePickerGlobal 日期选择器
SelectPickerGlobal 选项选择器
AmountKeyboard 金额键盘
PaymentPeriodRadio 缴费年期单选
RadioGroup 单选分组

模板 (PlanTemplates/)

组件 功能
SavingsTemplate 储蓄险模板
LifeInsuranceTemplate 寿险模板
CriticalIllnessTemplate 重疾险模板

图标组件 (icons/)

组件 功能 Props
IconFont IconFont 图标 name, size, color

使用示例

<template>
  <IconFont name="home" :size="28" color="#3B82F6" />
  <IconFont name="search" />
</template>

<script setup>
import IconFont from '@/components/icons/IconFont.vue'
</script>

🎯 组件使用规范

Props 定义

<script setup>
// ✅ GOOD - 有类型和默认值
const props = defineProps({
  title: {
    type: String,
    required: true
  },
  count: {
    type: Number,
    default: 0
  }
})

// ❌ BAD - 缺少类型
const props = defineProps(['title', 'count'])
</script>

Emits 定义

<script setup>
// ✅ GOOD - 明确定义事件
const emit = defineEmits(['update:modelValue', 'change', 'submit'])

// 使用
emit('update:modelValue', newValue)
emit('change', newValue)
</script>

样式规范

<style scoped>
/* ✅ 使用 TailwindCSS(80%) */
.container {
  @apply flex items-center justify-center p-4 bg-white rounded-lg;
}

/* ✅ 使用 Less(20%)- 深度选择器、特定样式 */
:deep(.nut-input) {
  border-radius: 12rpx !important;
}
</style>

🔧 核心组件详解

NavHeader.vue

页面顶部导航栏,支持返回按钮。

Props: | Prop | 类型 | 默认值 | 说明 | |------|------|--------|------| | title | String | - | 页面标题 | | showBack | Boolean | true | 是否显示返回按钮 | | preventDefaultBack | Boolean | false | 阻止默认返回行为 |

Events: | Event | 说明 | |-------|------| | back | 点击返回按钮时触发 |

使用示例

<NavHeader
  title="资料详情"
  :show-back="true"
  :prevent-default-back="true"
  @back="handleCustomBack"
/>

TabBar.vue

底部标签导航栏,支持红点提醒。

Props: | Prop | 类型 | 默认值 | 说明 | |------|------|--------|------| | current | String | 'home' | 当前激活的标签 |

红点自动同步

  • 组件自动从 userStore.tabBarBadges 读取红点状态
  • 无需手动传入 badges prop

使用示例

<TabBar current="home" />

MaterialCard.vue

资料/文档卡片,展示资料信息和操作按钮。

Props: | Prop | 类型 | 说明 | |------|------|------| | title | String | 资料标题 | | icon | String | 图标名称 | | learners | String | 学习人数 | | docType | String | 文档类型 | | fileSize | String | 文件大小 | | collected | Boolean | 是否已收藏 | | id | Number/String | 资料 ID |

Events: | Event | 说明 | |-------|------| | view | 查看资料 | | collect | 收藏/取消收藏 |


SearchBar.vue

搜索栏组件,支持清除和搜索。

Props: | Prop | 类型 | 默认值 | 说明 | |------|------|--------|------| | modelValue | String | '' | 绑定值(v-model) | | placeholder | String | '搜索' | 占位文本 | | disabled | Boolean | false | 是否禁用 | | showClear | Boolean | true | 是否显示清除按钮 |

Events: | Event | 说明 | |-------|------| | update:modelValue | 输入变化 | | search | 点击搜索或回车 |

使用示例

<SearchBar
  v-model="searchText"
  placeholder="搜索资料"
  @search="handleSearch"
/>

IconFont.vue

IconFont 图标组件。

Props: | Prop | 类型 | 默认值 | 说明 | |------|------|--------|------| | name | String | - | 图标名称 | | size | Number/String | 20 | 图标大小 | | color | String | '#333' | 图标颜色 |

使用示例

<IconFont name="home" :size="28" color="#3B82F6" />

📖 最佳实践

组件抽取原则

必须抽取为组件

  • ✅ UI 在 3 个及以上页面重复
  • ✅ 复杂的业务逻辑需要封装
  • ✅ 可复用的表单控件

组件命名规范

// ✅ GOOD - 多词组合,PascalCase
MaterialCard.vue
SearchBar.vue
AgePickerGlobal.vue

// ❌ BAD - 单词,不清晰
Card.vue
Input.vue
Picker.vue

Props vs Emits

<script setup>
// ✅ GOOD - 数据向下传递
const props = defineProps({
  modelValue: String
})

// ✅ GOOD - 事件向上传递
const emit = defineEmits(['update:modelValue', 'change'])

// 使用
emit('update:modelValue', newValue)
</script>

🔗 相关文档