Skip to content

快速开始 ​

DaLuoComponents 是基于 Vue 3 + Element Plus 的组件库,提供通用组件、富文本编辑器等开箱即用的组件。

安装 ​

前置依赖 ​

bash
# Node.js >= 18.0.0
# pnpm >= 9.0.0

使用 pnpm(推荐) ​

bash
pnpm add @axewo/fin-ui @axewo/fin-editor

安装核心包 ​

最简安装,仅安装通用组件:

bash
pnpm add @axewo/fin-ui element-plus

按需安装业务包 ​

根据实际需求安装对应的业务包:

bash
# 通用组件
pnpm add @axewo/fin-ui

# 富文本编辑器
pnpm add @axewo/fin-editor

# 全量包(包含所有组件)
pnpm add @axewo/fin-ui

全局注册(推荐) ​

在 main.ts 中全局注册组件库:

typescript
import { createApp } from 'vue'
import App from './App.vue'

// Element Plus
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import * as ElementPlusIconsVue from '@element-plus/icons-vue'

// DaLuoComponents
import FinCommon from '@axewo/fin-ui'
import '@axewo/fin-ui/dist/style.css'

const app = createApp(App)

// 注册 Element Plus
app.use(ElementPlus)

// 注册 Element Plus 图标
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
  app.component(key, component)
}

// 注册 DaLuoComponents
app.use(FinCommon)

app.mount('#app')

按需引入 ​

如果只想使用部分组件,可以按需引入:

vue
<script setup lang="ts">
import { FCrudTable, FForm, FTableSelect } from '@axewo/fin-ui'
import '@axewo/fin-ui/dist/style.css'
</script>

<template>
  <FCrudTable :config="tableConfig" />
</template>

配置提供器 ​

使用 FinConfigProvider 统一配置全局参数:

vue
<script setup lang="ts">
import { FinConfigProvider } from '@axewo/fin-ui'

// 字典数据加载器
async function loadDict(dictType: string) {
  const res = await fetch(`/api/dict/${dictType}`)
  return res.json()
}

// 文件上传服务
async function uploadFile(file: File) {
  const formData = new FormData()
  formData.append('file', file)
  const res = await fetch('/api/upload', { method: 'POST', body: formData })
  return res.json()
}
</script>

<template>
  <FinConfigProvider
    :dict="{ loader: loadDict, fieldNames: { label: 'name', value: 'code' } }"
    :upload="{ handler: uploadFile }"
  >
    <RouterView />
  </FinConfigProvider>
</template>

第一个示例 ​

创建一个简单的 CRUD 表格:

vue
<script setup lang="ts">
import { ref } from 'vue'
import { FCrudTable } from '@axewo/fin-ui'
import type { TableConfig } from '@axewo/fin-ui'

// 模拟 API
async function fetchList(params: any) {
  return {
    data: {
      list: [
        { id: 1, name: '张三', age: 28, dept: '技术部', status: 'active' },
        { id: 2, name: '李四', age: 32, dept: '财务部', status: 'active' },
        { id: 3, name: '王五', age: 25, dept: '市场部', status: 'inactive' },
      ],
      total: 3,
    },
  }
}

const tableConfig: TableConfig = {
  columns: [
    { field: 'id', label: 'ID', width: 80 },
    {
      field: 'name',
      label: '姓名',
      formItem: {
        component: 'FInput',
        required: true,
        search: true,
      },
    },
    {
      field: 'age',
      label: '年龄',
      formItem: {
        component: 'FInputNumber',
      },
    },
    {
      field: 'dept',
      label: '部门',
      formItem: {
        component: 'FSelect',
        componentProps: {
          options: [
            { label: '技术部', value: '技术部' },
            { label: '财务部', value: '财务部' },
            { label: '市场部', value: '市场部' },
          ],
        },
        search: true,
      },
    },
    {
      field: 'status',
      label: '状态',
      formatter: 'status',
      formatterOptions: {
        statusMap: {
          active: { label: '在职', type: 'success' },
          inactive: { label: '离职', type: 'info' },
        },
      },
    },
  ],
  requestConfig: {
    api: fetchList,
  },
  crudConfig: {
    createApi: async (data) => {
      console.log('新增:', data)
      return { success: true }
    },
    updateApi: async (data) => {
      console.log('编辑:', data)
      return { success: true }
    },
    deleteApi: async (row) => {
      console.log('删除:', row)
      return { success: true }
    },
  },
}
</script>

<template>
  <FCrudTable :config="tableConfig" />
</template>

表单内置组件清单 ​

FForm 当前在共享注册表中预注册以下 23 个字段类型。名称区分大小写,须在 FormSchema.component 中使用表中的准确名称:

组件名实现
FInputElInput
FTextareaElInput(自动设置 type="textarea")
FInputNumberElInputNumber
FSelectElSelect
FTableSelectFinTableSelect
FLangInputFinLangInput
FDictSelectFinDictSelect
FDictRadioFinDictRadio
FCascaderElCascader
FTreeSelectElTreeSelect
FTreeFinTree(标准 v-model,支持单选 key 或复选 key 数组)
FDatePickerElDatePicker
FDateRangeElDatePicker(自动设置 type="daterange")
FTimePickerElTimePicker
FTimeSelectElTimeSelect
FSwitchElSwitch
FRadioElRadioGroup
FCheckboxElCheckboxGroup
FRateElRate
FSliderElSlider
FColorPickerElColorPicker
FTransferElTransfer
FAutocompleteElAutocomplete

FUpload、FMoneyInput 和 FPeriodPicker 并非内置类型;如需使用,请按下节自行注册。


自定义字段组件注册 ​

字段注册表是模块级共享注册表,不是 FinConfigProvider 属性。使用 registerFormField 注册一个组件,或使用 registerFormFields 批量注册;建议自定义名称也采用 F 前缀。

typescript
import {
  registerFormField,
  registerFormFields,
} from '@axewo/fin-ui'
import AccountSelector from './components/AccountSelector.vue'
import AmountInput from './components/AmountInput.vue'
import PeriodPicker from './components/PeriodPicker.vue'

registerFormField('FAccountSelector', AccountSelector)

registerFormFields({
  FAmountInput: AmountInput,
  FPeriodPicker: PeriodPicker,
})

注册应在应用渲染表单之前执行。之后即可通过准确的注册名引用:

typescript
import type { FormSchema } from '@axewo/fin-ui'

const schemas: FormSchema[] = [
  {
    field: 'accountId',
    label: '账户',
    component: 'FAccountSelector',
  },
]

TypeScript 支持 ​

DaLuoComponents 使用 TypeScript 编写,提供完整的类型定义。

typescript
import type {
  TableConfig,
  TableColumnConfig,
  FormSchema,
  UseFormProps,
  ActionButtonConfig,
} from '@axewo/fin-ui'

const tableConfig: TableConfig = {
  // 完整的类型提示和校验
}

下一步 ​


常见问题 ​

1. Element Plus 样式没有生效? ​

确保在 main.ts 中引入了 Element Plus 的样式:

typescript
import 'element-plus/dist/index.css'

2. 组件未定义 / 找不到组件? ​

确保已全局注册或按需引入组件:

typescript
import { FCrudTable } from '@axewo/fin-ui'

3. 如何处理组件的 v-model 绑定? ​

所有表单组件均支持 v-model 双向绑定:

vue
<template>
  <FForm v-model="formData" :config="formConfig" />
</template>

4. 如何自定义表格列渲染? ​

使用 slot 属性指定插槽名:

typescript
{
  field: 'status',
  label: '状态',
  slot: 'status',
}
vue
<template>
  <FCrudTable :config="tableConfig">
    <template #cell-status="{ row }">
      <el-tag :type="row.status === 'active' ? 'success' : 'info'">
        {{ row.status }}
      </el-tag>
    </template>
  </FCrudTable>
</template>

5. 如何实现表单联动? ​

使用 ifShow 或 disabled 函数实现联动:

typescript
{
  field: 'province',
  label: '省份',
  component: 'FSelect',
},
{
  field: 'city',
  label: '城市',
  component: 'FSelect',
  // 省份未选择时隐藏城市
  ifShow: ({ model }) => !!model.province,
}