npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@ithinkdt/ui

v4.2.6

Published

iThinkDT UI

Readme

@ithinkdt/ui

许可证

MIT

安装

npm i @ithinkdt/ui

需要您自行安装 peer 依赖 vue@>=3.5vue-router@>=4.5ithinkdt-ui@>=1.5。如果使用页面渲染适配能力,需要安装 @ithinkdt/page@>=4.0;如果使用 UnoCSS 预设,需要安装 unocss@>=66

介绍

@ithinkdt/ui 提供 iThinkDT 应用 UI 层的组件、指令与渲染适配能力,包括:

  • 应用布局、侧栏、菜单、面包屑、页签、通知、租户、账号、语言、外观切换组件
  • 数据表单、查询筛选、数据表格、分页、批量选择、列自定义、详情描述组件
  • 单选、多选、人员/部门选择、国际化输入、状态按钮等业务组件
  • v-spinv-tooltip 指令
  • @ithinkdt/page 对接的表单项、详情、模态框渲染器
  • UnoCSS 主题色、圆角、快捷类与命名空间隔离预设
  • 自动导入配置

初始化

注册 UI 上下文与指令 Provider

UIProvider 用于注入 UI 文案国际化能力;SpinDirectiveProviderTooltipDirectiveProvider 用于挂载 v-spinv-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 | 应用布局容器,支持 left2righttop2bottom | | 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>

支持 lightdark 修饰符;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'