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

h5-tdsign-for-vue

v0.1.18

Published

基于 TDesign Mobile 的 Vue 3 智能表单组件库

Readme

h5-tdsign-for-vue

基于 TDesign Mobile Vue 的智能表单组件库,提供开箱即用的动态表单解决方案。

npm version license

✨ 特性

  • 🚀 动态表单 - 通过 JSON Schema 配置生成表单,无需手写模板
  • 📱 移动端优化 - 基于 TDesign Mobile,完美适配移动端
  • 🎯 TypeScript - 完整的类型定义,提供良好的开发体验
  • 🔌 自动引入 - 支持 unplugin-vue-components 自动按需引入
  • 🎨 丰富组件 - 内置多种表单控件,满足常见业务场景

📦 安装

# npm
npm install h5-tdsign-for-vue

# pnpm
pnpm add h5-tdsign-for-vue

# yarn
yarn add h5-tdsign-for-vue

前置依赖

pnpm add vue tdesign-mobile-vue

🚀 快速开始

全局注册

// main.ts
import { createApp } from 'vue'
import TDesign from 'tdesign-mobile-vue'
import 'tdesign-mobile-vue/es/style/index.css'
import { SmartForm, SmartUpload } from 'h5-tdsign-for-vue'
import 'h5-tdsign-for-vue/style.css'

const app = createApp(App)
app.use(TDesign)
app.component('SmartForm', SmartForm)
app.component('SmartUpload', SmartUpload)
app.mount('#app')

自动引入(推荐)

// vite.config.ts
import Components from 'unplugin-vue-components/vite'
import { SmartFormResolver } from 'h5-tdsign-for-vue/resolver'

export default defineConfig({
  plugins: [
    Components({
      resolvers: [SmartFormResolver()],
    }),
  ],
})

📖 组件文档

SmartForm 智能表单

通过 JSON Schema 配置生成动态表单。

<template>
  <SmartForm
    v-model="formData"
    :schemas="schemas"
    @submit="handleSubmit"
  />
</template>

<script setup lang="ts">
import { ref } from 'vue'
import type { FormSchema } from 'h5-tdsign-for-vue'

interface FormData {
  name: string
  phone: string
  gender: string
}

const formData = ref<FormData>({
  name: '',
  phone: '',
  gender: '',
})

const schemas: FormSchema<FormData>[] = [
  {
    name: 'name',
    label: '姓名',
    type: 'input',
    required: true,
    requiredMark: false, // 隐藏必填星号
    props: { placeholder: '请输入姓名' },
  },
  {
    name: 'idCard',
    label: '身份证号', // 配合 showLabel: false 可隐藏标签
    showLabel: false, // 隐藏标签
    type: 'input',
    props: { placeholder: '请输入身份证号' },
  },
  {
    name: 'phone',
    label: '手机号',
    type: 'input',
    props: { type: 'tel', placeholder: '请输入手机号' },
  },
  {
    name: 'gender',
    label: '性别',
    type: 'select',
    props: {
      columns: [
        { label: '男', value: 'male' },
        { label: '女', value: 'female' },
      ],
    },
  },
]

const handleSubmit = (data: FormData) => {
  console.log('提交数据:', data)
}
</script>

Props

| 属性 | 说明 | 类型 | 默认值 | |------|------|------|--------| | modelValue | 表单数据 | T | - | | schemas | 表单配置 | FormSchema<T>[] | [] | | labelWidth | 标签宽度 | string \| number | - | | labelAlign | 标签对齐 | 'left' \| 'right' \| 'top' | 'left' | | showFooter | 显示底部按钮 | boolean | true | | submitBtnText | 提交按钮文字 | string | '提交' | | resetBtnText | 重置按钮文字 | string | '重置' | | loading | 加载状态 | boolean | false | | disabled | 禁用状态 | boolean | false |

Slots

| 插槽 | 说明 | 参数 | |------|------|------| | default | 表单内容插槽(通常不需要手动使用) | - | | footer-top | 底部按钮上方的自定义内容插槽 | - |

FormSchema 配置

基础配置项:

| 属性 | 说明 | 类型 | 默认值 | |------|------|------|--------| | name | 字段名 | string | - | | label | 标签文本 | string | - | | type | 组件类型 | ComponentType | 'input' | | required | 是否必填 | boolean | false | | requiredMark | 显示必填星号 | boolean | true | | showLabel | 显示标签 | boolean | true | | hidden | 是否隐藏 | boolean \| ((model) => boolean) | false | | disabled | 是否禁用 | boolean \| ((model) => boolean) | false | | props | 组件属性 | object | {} | | rules | 校验规则 | FormRule[] | [] |

支持的组件类型

| type | 说明 | 对应组件 | |------|------|----------| | input | 输入框 | Input | | textarea | 多行文本 | Textarea | | password | 密码输入 | Input | | number | 数字输入 | Input | | select | 选择器 | SmartSelect | | cascader | 级联选择 | SmartCascader | | tree-select | 树形选择 | SmartTreeSelect | | date | 日期选择 | SmartTimePicker | | time | 时间选择 | SmartTimePicker | | switch | 开关 | Switch | | radio | 单选 | RadioGroup | | checkbox | 多选 | CheckboxGroup | | stepper | 步进器 | Stepper | | upload | 上传 | SmartUpload | | slot | 自定义插槽 | - |


SmartUpload 智能上传

支持多种数据格式的图片/文件上传组件。

<template>
  <SmartUpload
    v-model="fileList"
    :request-method="uploadFile"
    :format-response="formatResponse"
    value-type="objectArray"
    url-key="fileUrl"
    name-key="filename"
  />
</template>

<script setup lang="ts">
import { ref } from 'vue'

interface FileData {
  id: number
  filename: string
  fileUrl: string
}

const fileList = ref<FileData[]>([])

const uploadFile = async (file: File) => {
  const formData = new FormData()
  formData.append('file', file)
  const res = await fetch('/api/upload', { method: 'POST', body: formData })
  return { status: 'success', response: await res.json() }
}

const formatResponse = (res: any) => ({
  id: res.data.id,
  filename: res.data.name,
  fileUrl: res.data.url,
})
</script>

Props

| 属性 | 说明 | 类型 | 默认值 | |------|------|------|--------| | modelValue | 文件列表 | string \| string[] \| object[] | '' | | valueType | 值类型 | 'string' \| 'stringArray' \| 'objectArray' | 自动推断 | | urlKey | URL 字段名 | string | 'fileUrl' | | nameKey | 名称字段名 | string | 'filename' | | separator | 分隔符 | string | ',' | | urlPrefix | URL 前缀 | string | '' | | mode | 上传模式 | 'image' \| 'file' | 'image' | | accept | 接受类型 | string \| string[] | 'image/*' | | max | 最大数量 | number | 9 | | maxSize | 最大大小(KB) | number | 10240 | | multiple | 多选 | boolean | true | | disabled | 禁用 | boolean | false | | requestMethod | 上传方法 | Function | - | | formatResponse | 格式化响应 | Function | - |


SmartSelect 选择器

带输入框触发的选择器组件。

<SmartSelect
  v-model="value"
  label="城市"
  placeholder="请选择城市"
  :columns="[
    { label: '北京', value: 'beijing' },
    { label: '上海', value: 'shanghai' },
  ]"
/>

SmartCascader 级联选择

多级联动选择器。

<SmartCascader
  v-model="value"
  label="地区"
  placeholder="请选择地区"
  :options="areaOptions"
/>

SmartTreeSelect 树形选择

树形结构选择器。

<SmartTreeSelect
  v-model="value"
  label="部门"
  placeholder="请选择部门"
  :options="deptOptions"
/>

SmartTimePicker 时间选择器

日期/时间选择器。

<SmartTimePicker
  v-model="value"
  label="日期"
  placeholder="请选择日期"
  mode="date"
  format="YYYY-MM-DD"
/>

SmartList 智能列表

支持下拉刷新、上拉加载、骨架屏的列表组件。

<template>
  <SmartList
    v-model:pagination="pagination"
    :fetch-api="fetchList"
    :skeleton-rows="5"
    finished-text="— 没有更多了 —"
  >
    <template #item="{ item, index }">
      <div class="list-item">
        <span>{{ index + 1 }}. {{ item.title }}</span>
      </div>
    </template>
  </SmartList>
</template>

<script setup lang="ts">
import { reactive } from 'vue'

interface ListItem {
  id: number
  title: string
}

const pagination = reactive({
  pageNum: 1,
  pageSize: 10,
  total: 0,
})

const fetchList = async (params: Record<string, unknown>): Promise<ListItem[]> => {
  const res = await fetch(`/api/list?page=${params.pageNum}&size=${params.pageSize}`)
  const data = await res.json()
  pagination.total = data.total
  return data.list
}
</script>

Props

| 属性 | 说明 | 类型 | 默认值 | |------|------|------|--------| | fetchApi | 获取数据的 API 函数 | (params) => Promise<T[]> | - | | pagination | 分页对象(v-model) | Record<string, number> | - | | paginationConfig | 分页字段映射 | PaginationConfig | 见下方 | | immediate | 是否立即加载 | boolean | true | | pullDownRefresh | 启用下拉刷新 | boolean | true | | pullUpLoad | 启用上拉加载 | boolean | true | | loadMode | 加载模式 | 'auto' \| 'click' | 'auto' | | loadOffset | 自动加载触发距离 | number | 50 | | skeleton | 显示骨架屏 | boolean | true | | skeletonRows | 骨架屏行数 | number | 5 | | finishedText | 加载完成提示 | string | '没有更多了' | | emptyText | 空状态提示 | string | '暂无数据' |

PaginationConfig 默认值

{
  pageKey: 'pageNum',
  pageSizeKey: 'pageSize',
  totalKey: 'total',
}

Events

| 事件 | 说明 | 参数 | |------|------|------| | update:pagination | 分页更新 | pagination | | load-success | 加载成功 | { list, isRefresh } | | load-error | 加载失败 | error | | refresh | 下拉刷新 | - | | load-more | 上拉加载 | - |

Slots

| 插槽 | 说明 | 参数 | |------|------|------| | item | 列表项 | { item, index } | | skeleton | 骨架屏 | - | | empty | 空状态 | - | | loading | 加载中 | - | | finished | 加载完成 | - | | header | 列表头部 | - | | footer | 列表底部 | - |

Methods(通过 ref 调用)

| 方法 | 说明 | |------|------| | refresh() | 刷新列表 | | getList() | 获取当前数据 | | scrollToTop() | 滚动到顶部 |


SmartPage 页面容器

集成 Navbar 和 TabBar 的页面根组件,提供统一的页面布局方案。

<template>
  <SmartPage
    title="首页"
    show-back
    show-tab-bar
    v-model:tab-bar-value="activeTab"
    :tabs="tabList"
    @back="handleBack"
    @tab-change="handleTabChange"
  >
    <div class="page-content">
      页面内容
    </div>
  </SmartPage>
</template>

<script setup lang="ts">
import { ref, h } from 'vue'
import { Icon as TIcon } from 'tdesign-mobile-vue'
import type { TabItem } from 'h5-tdsign-for-vue'

const activeTab = ref('home')

// 创建图标组件 - 支持 TDesign Icon、图片、SVG
const HomeIcon = () => h(TIcon, { name: 'home' })
const UserIcon = () => h(TIcon, { name: 'user' })

// 使用自定义图片作为图标
const CustomIcon = () => h('img', { src: '/icons/custom.png', style: { width: '24px' } })

const tabList: TabItem[] = [
  { value: 'home', label: '首页', icon: HomeIcon },
  { value: 'user', label: '我的', icon: UserIcon, badgeProps: { count: 5 } },
]

const handleBack = () => {
  console.log('返回')
}

const handleTabChange = (value: string | number) => {
  console.log('切换到:', value)
}
</script>

<style scoped>
.page-content {
  /* 设置 height: 100% 可以正确撑满内容区域 */
  height: 100%;
  overflow: auto;
}
</style>

Props

| 属性 | 说明 | 类型 | 默认值 | |------|------|------|--------| | title | 页面标题 | string | - | | showNavbar | 显示顶部导航栏 | boolean | true | | showBack | 显示返回按钮 | boolean | false | | onBack | 自定义返回逻辑 | () => void | window.history.back() | | showTabBar | 显示底部标签栏 | boolean | false | | tabs | 标签栏配置 | TabItem[] | [] | | tabBarValue | 当前选中标签(支持 v-model) | string \| number | - |

Navbar 相关属性

| 属性 | 说明 | 类型 | 默认值 | |------|------|------|--------| | navbarAnimation | 标题切换动画 | boolean | true | | navbarFixed | 固定在顶部 | boolean | true | | navbarPlaceholder | 固定时是否占位 | boolean | true | | navbarSafeAreaInsetTop | 安全区域适配 | boolean | true | | navbarZIndex | 层级 | number | - |

TabBar 相关属性

| 属性 | 说明 | 类型 | 默认值 | |------|------|------|--------| | tabBarBordered | 显示边框 | boolean | true | | tabBarFixed | 固定在底部 | boolean | true | | tabBarPlaceholder | 固定时是否占位 | boolean | true | | tabBarSafeAreaInsetBottom | 安全区域适配 | boolean | true | | tabBarShape | 形状 | 'round' \| 'normal' | 'round' | | tabBarTheme | 主题 | 'normal' \| 'tag' | 'normal' | | tabBarZIndex | 层级 | number | - |

TabItem 配置

| 属性 | 说明 | 类型 | 必填 | |------|------|------|------| | value | 标签值 | string \| number | ✅ | | label | 标签文本 | string | - | | icon | 图标组件 | Component | - | | badgeProps | 徽标配置 | TdBadgeProps | - |

Events

| 事件 | 说明 | 参数 | |------|------|------| | back | 点击返回按钮 | - | | tab-change | 切换标签 | (value: string \| number) | | update:tabBarValue | 标签值变更 | (value: string \| number) | | right-click | 点击导航栏右侧 | - |

Slots

| 插槽 | 说明 | |------|------| | default | 页面内容 | | navbar-left | 导航栏左侧自定义内容 | | navbar-right | 导航栏右侧自定义内容 | | navbar-title | 导航栏标题自定义内容 | | navbar-capsule | 导航栏胶囊区域 |

自定义图标

支持多种图标类型:

import { h } from 'vue'
import { Icon as TIcon } from 'tdesign-mobile-vue'
import CustomSvgIcon from '@/icons/CustomIcon.vue'

// 1. TDesign Icon
const TdIcon = () => h(TIcon, { name: 'home' })

// 2. 图片图标
const ImageIcon = () => h('img', { 
  src: '/icons/home.png', 
  style: { width: '24px', height: '24px' } 
})

// 3. 内联 SVG
const SvgIcon = () => h('svg', { viewBox: '0 0 24 24' }, [
  h('path', { d: 'M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z', fill: 'currentColor' })
])

// 4. Vue 组件
const VueIcon = CustomSvgIcon

📝 类型导出

import type {
  // SmartForm 相关
  FormSchema,
  SmartFormProps,
  ComponentType,
  // SmartUpload 相关
  SmartUploadProps,
  SmartUploadFile,
  FileListValue,
  FileListValueType,
  // SmartPage 相关
  SmartPageProps,
  TabItem,
  // SmartList 相关
  SmartListProps,
  PaginationConfig,
} from 'h5-tdsign-for-vue'

🔧 开发

# 安装依赖
pnpm install

# 启动开发服务器
pnpm dev

# 构建组件库
pnpm build:lib

# 类型检查
pnpm type-check

# 代码检查
pnpm lint

📄 License

MIT