@ithinkdt/ui
v4.2.6
Published
iThinkDT UI
Readme
@ithinkdt/ui
许可证
MIT
安装
npm i @ithinkdt/ui需要您自行安装 peer 依赖
vue@>=3.5、vue-router@>=4.5与ithinkdt-ui@>=1.5。如果使用页面渲染适配能力,需要安装@ithinkdt/page@>=4.0;如果使用 UnoCSS 预设,需要安装unocss@>=66。
介绍
@ithinkdt/ui 提供 iThinkDT 应用 UI 层的组件、指令与渲染适配能力,包括:
- 应用布局、侧栏、菜单、面包屑、页签、通知、租户、账号、语言、外观切换组件
- 数据表单、查询筛选、数据表格、分页、批量选择、列自定义、详情描述组件
- 单选、多选、人员/部门选择、国际化输入、状态按钮等业务组件
v-spin、v-tooltip指令- 与
@ithinkdt/page对接的表单项、详情、模态框渲染器 - UnoCSS 主题色、圆角、快捷类与命名空间隔离预设
- 自动导入配置
初始化
注册 UI 上下文与指令 Provider
UIProvider 用于注入 UI 文案国际化能力;SpinDirectiveProvider 与 TooltipDirectiveProvider 用于挂载 v-spin、v-tooltip 所需的全局样式与浮层。
import { createApp } from 'vue'
import {
SpinDirectiveProvider,
TooltipDirectiveProvider,
UIProvider,
vSpin,
vTooltip,
} from '@ithinkdt/ui'
import App from './App.vue'
const app = createApp({
setup() {
return () => (
<UIProvider>
<SpinDirectiveProvider />
<TooltipDirectiveProvider />
<App />
</UIProvider>
)
},
})
app.directive('spin', vSpin)
app.directive('tooltip', vTooltip)
app.mount('#app')如果项目已经使用 @ithinkdt/vite 的自动导入能力,可以直接使用 @ithinkdt/ui/auto-imports。
import ImportsUI, { UIComponents, UIDirectives } from '@ithinkdt/ui/auto-imports'
export default {
plugins: [
presets({
components: {
resolvers: [
...UIComponents,
...UIDirectives,
],
},
autoImport: {
imports: [
...ImportsUI,
],
},
}),
],
}UnoCSS 预设
import ithinkdt from '@ithinkdt/ui/unocss'
import { defineConfig } from 'unocss'
export default defineConfig({
presets: [
ithinkdt(),
],
})开启命名空间隔离时,UnoCSS 变量和选择器会被限定在指定容器内:
export default defineConfig({
presets: [
ithinkdt({ namespace: 'my-app' }),
],
})应用布局
基础布局
import {
AppAccount,
AppContent,
AppHeader,
AppLayout,
AppLogo,
AppMenu,
AppSidebar,
} from '@ithinkdt/ui'
const menus = [
{
type: 'view',
key: 'home',
name: '首页',
path: '/',
},
{
type: 'group',
key: 'system',
name: '系统管理',
children: [
{ type: 'view', key: 'user', name: '用户管理', path: '/users' },
{ type: 'view', key: 'role', name: '角色管理', path: '/roles' },
],
},
]
export default {
setup() {
const collapsed = ref(false)
return () => (
<AppLayout layout="left2right">
<AppSidebar v-model:collapsed={collapsed.value}>
<AppLogo name="管理后台" collapsed={collapsed.value} />
<AppMenu menus={menus} current="home" collapsed={collapsed.value} />
</AppSidebar>
<AppLayout>
<AppHeader>
<AppAccount
username="zhangsan"
nickname="张三"
onLogout={() => console.log('logout')}
/>
</AppHeader>
<AppContent>
<RouterView />
</AppContent>
</AppLayout>
</AppLayout>
)
},
}常用应用组件
| 组件 | 说明 |
|------|------|
| AppLayout | 应用布局容器,支持 left2right 与 top2bottom |
| AppHeader | 顶部栏 |
| AppSidebar | 侧边栏,支持折叠 |
| AppContent | 内容区,支持 naive / native 滚动条 |
| AppFooter | 底部栏 |
| AppLogo | 应用 Logo 与应用名 |
| AppMenu | 应用模块菜单 |
| AppBreadcrumb | 面包屑 |
| AppAccount | 用户账号下拉 |
| AppFullscreen | 全屏切换 |
| AppAppearance | 明暗主题切换 |
| AppLanguage | 语言切换 |
| AppMultiTabs | 多页签 |
| AppNotification | 消息通知 |
| AppTenant | 租户切换 |
数据组件
数据组件需要从 @ithinkdt/ui/components 导入。
数据表单
DataForm 负责渲染 @ithinkdt/page 的表单项定义。
import { DataForm } from '@ithinkdt/ui/components'
import { useFormHelper } from '@ithinkdt/page'
export default {
setup() {
const { model, items, validate, reset } = useFormHelper(
({ it }) => [
it('name', '姓名', 'input', { required: true }),
it('age', '年龄', 'number'),
it('status', '状态', 'select', {
selectProps: {
options: [
{ label: '启用', value: '1' },
{ label: '禁用', value: '0' },
],
},
}),
],
{ initial: { name: '', status: '1' } },
)
async function submit() {
const [valid] = await validate()
if (valid) {
console.log(model)
}
}
return () => (
<DataForm
model={model}
items={items}
grid={{ cols: 12 }}
showColon
onSubmit={submit}
onReset={reset}
/>
)
},
}查询筛选
import { DataFilter } from '@ithinkdt/ui/components'
import { useFilterHelper } from '@ithinkdt/page'
const { model, items, reset } = useFilterHelper(({ it }) => [
it('keyword', '关键字', 'input'),
it('status', '状态', 'select', {
selectProps: {
options: statusOptions,
},
}),
])
return () => (
<DataFilter
model={model}
items={items}
collapsible
onFilter={(filter) => ds.pull({ currentPage: 1 }, filter)}
onReset={reset}
/>
)数据表格与分页
import { DataPagination, DataTable } from '@ithinkdt/ui/components'
import { useDs, useTableHelper } from '@ithinkdt/page'
const ds = useDs(userApi.page, { pagination: 'remote' })
const { columns } = useTableHelper(({ col }) => [
col('name', '姓名', { width: 140 }),
col('email', '邮箱', { width: 220 }),
col('status', '状态', 'dict', {
dictParams: {
options: [
{ label: '启用', value: '1' },
{ label: '禁用', value: '0' },
],
},
}),
])
return () => (
<>
<DataTable
data={ds.data}
columns={columns.value}
sorter={ds.sorter}
selectedKeys={selectedKeys.value}
onSort={ds.sort}
onSelect={(keys) => selectedKeys.value = keys}
/>
<DataPagination
page={ds.page}
total={ds.total}
onChange={ds.pull}
/>
</>
)其他数据组件
| 组件 / 方法 | 说明 |
|-------------|------|
| DataFormActions | 表单提交、重置、取消按钮组 |
| DataSelection | 批量选择状态展示,支持当前页 / 全部切换 |
| DataCustom | 表格列排序、隐藏、固定配置 |
| DataActions | 表格操作列按钮渲染 |
| DataDescriptions | 详情描述展示 |
| DataLocaleInput | 多语言输入 |
| useLocaleEdit | 多语言内容弹窗编辑 |
| NStateButton | 带成功 / 失败状态的按钮 |
| NCheckboxes | 字典友好的多选组 |
| NRadios | 字典友好的单选组 |
| DtUserDept | 用户 / 部门选择 |
| DtUserRender | 用户显示 |
| DtDeptRender | 部门显示 |
与 @ithinkdt/page 集成
@ithinkdt/ui/page 提供 @ithinkdt/page 所需的渲染器,建议在 @ithinkdt/page 插件初始化时注册。
import pagePlugin from '@ithinkdt/page'
import { DataActions } from '@ithinkdt/ui/components'
import {
createDescriptionHelper,
createFormHelper,
createFormItemHelper,
createModalHelper,
} from '@ithinkdt/ui/page'
app.use(pagePlugin, {
getFormRenderer: createFormHelper(),
getModalRenderer: createModalHelper(),
getFormItemRenderer: createFormItemHelper({
uploadFile: async (file) => {
const formData = new FormData()
formData.append('file', file)
const res = await fetch('/api/files', { method: 'POST', body: formData })
return await res.text()
},
getFileInfos: async (ids) => {
return await fetch('/api/files/info', {
method: 'POST',
body: JSON.stringify(ids),
}).then(res => res.json())
},
getUserGroups: async () => [],
getUsersByGroup: async () => [],
getUsersByDept: async () => [],
getUsersByUsername: async () => [],
getDeptsByCode: async () => [],
}),
getDescriptionRenderer: createDescriptionHelper({
getFileInfos: async ids => [],
previewFileUrl: id => `/api/files/${id}/preview`,
getUsersByUsername: async usernames => [],
getDeptsByCode: async codes => [],
}),
getTableActionsRenderer: () => actions => <DataActions options={actions} />,
})内置表单项类型
| 类型 | 说明 |
|------|------|
| input | 文本输入 |
| number | 数字输入,支持 valueType |
| select | 下拉选择,支持字典、远程 options、valueType |
| checkbox | 单个复选框 |
| checkboxes | 复选框组 |
| radios | 单选组 |
| datepicker | 日期选择 |
| file | 文件选择 |
| upload | 文件上传 |
| user | 用户 / 部门选择 |
内置详情类型
| 类型 | 说明 |
|------|------|
| longtext | 长文本抽屉查看,支持复制 |
| number | 数字格式化,支持小数、百分比、千分位 |
| date | 日期格式化 |
| datetime | 日期时间格式化 |
| dict | 字典显示,支持状态色 |
| email | 邮箱链接 |
| url | URL 链接 |
| color | 颜色展示 |
| file | 文件链接 |
| image | 图片预览 |
| user | 用户展示 |
| dept | 部门展示 |
指令
v-spin
<template>
<section v-spin="loading" data-spin-tip="加载中...">
...
</section>
<section v-spin.dark="submitting">
...
</section>
</template>支持 light、dark 修饰符;data-spin-tip 可设置提示文字。
v-tooltip
<template>
<span v-tooltip.auto="'完整内容'">
很长的内容
</span>
<p v-tooltip.auto.expandable.ell3="detail">
{{ detail }}
</p>
<button v-tooltip.bottom="'保存'">
保存
</button>
</template>常用修饰符:
| 修饰符 | 说明 |
|--------|------|
| auto | 内容溢出时才展示提示 |
| expandable | 内容溢出时支持点击展开 |
| ell2 / ell3 / ell5 | 多行省略 |
| top / right / bottom / left | 提示位置 |
| top-start / bottom-end 等 | 细分提示位置 |
组合式 API
useDataTableDrag
用于给 DataTable 或其他表格 DOM 添加拖拽排序能力。
import { useTemplateRef } from 'vue'
import { useDataTableDrag } from '@ithinkdt/ui/composables'
const tableRef = useTemplateRef<HTMLElement>('table')
const data = ref([
{ id: '1', name: '张三' },
{ id: '2', name: '李四' },
])
useDataTableDrag(tableRef, {
data,
handle: '.drag-handle',
onSort({ from, to }) {
const [item] = data.value.splice(from, 1)
data.value.splice(to, 0, item)
},
})样式工具
@ithinkdt/ui/use-style 重新导出 ithinkdt-ui 的 CSSR 工具,并提供常用样式对象。
import useStyle, {
c,
cB,
cE,
cM,
flexCenter,
fullWH,
useClsPrefix,
} from '@ithinkdt/ui/use-style'常用导出:
| 导出 | 说明 |
|------|------|
| useStyle | 挂载 CSSR 样式 |
| useClsPrefix | 获取组件 class 前缀 |
| c / cB / cE / cM | CSSR 选择器工具 |
| fullWidth / fullHeight / fullWH | 宽高工具对象 |
| flex / flexDirCol | Flex 基础工具对象 |
| flexAlignCenter / flexJustifyCenter / flexCenter | 居中工具对象 |
| flexJustifySB / flexGap | Flex 排布工具对象 |
导入路径
// 应用布局、指令 Provider、根 UIProvider
import { AppLayout, UIProvider, vSpin, vTooltip } from '@ithinkdt/ui'
// 数据组件
import { DataForm, DataTable, DataPagination } from '@ithinkdt/ui/components'
// 指令
import { vSpin, vTooltip } from '@ithinkdt/ui/directives'
// 与 @ithinkdt/page 集成的渲染器
import { createFormItemHelper } from '@ithinkdt/ui/page'
// 组合式 API
import { useDataTableDrag } from '@ithinkdt/ui/composables'
// 样式工具
import useStyle from '@ithinkdt/ui/use-style'
// UnoCSS 预设
import ithinkdt from '@ithinkdt/ui/unocss'