@ai-low-form/tdesign-mobile-form
v1.0.2
Published
A mobile form component for Vue 3 with TDesign Mobile
Maintainers
Readme
@ai-low-form/tdesign-mobile-form
基于 Vue 3 + TDesign Mobile 的移动端配置化表单组件,通过 JSON 配置即可快速生成复杂的表单。
✨ 特性
- 🚀 配置化驱动:通过 JSON 配置快速生成表单
- 📱 移动端优化:基于 TDesign Mobile Vue 组件
- 🎨 动态布局:支持动态设置标签对齐方式
- ✅ 内置验证:支持必填、正则、自定义验证规则
- 🔄 数据转换:支持表单数据的双向转换
- 🎯 TypeScript:完整的类型定义
- 🔌 高度可扩展:支持自定义组件和万能插槽
📦 安装
# 使用 npm
npm install @ai-low-form/tdesign-mobile-form
# 使用 pnpm
pnpm add @ai-low-form/tdesign-mobile-form
# 使用 yarn
yarn add @ai-low-form/tdesign-mobile-form🚀 快速开始
1. 全局注册 TDesign 组件
// main.ts
import { createApp } from 'vue';
import TDesign from 'tdesign-mobile-vue';
import 'tdesign-mobile-vue/es/style/index.css';
import App from './App.vue';
const app = createApp(App);
app.use(TDesign);
app.mount('#app');2. 基础使用
<script setup lang="ts">
import { ref } from 'vue';
import { MobileForm } from '@ai-low-form/tdesign-mobile-form';
import type { MobileFormRef, MobileFormConfig } from '@ai-low-form/tdesign-mobile-form';
// 表单引用
const formRef = ref<MobileFormRef>();
// 表单配置
const formConfig: MobileFormConfig = {
// 表单项配置
items: [
{
label: '用户名',
prop: 'username',
required: true,
},
{
label: '邮箱',
prop: 'email',
component: {
name: 't-input',
props: {
placeholder: '请输入邮箱',
type: 'email',
},
},
required: true,
rules: {
pattern: /^[^\s@]+@[^\s@]+\.[^\s@]+$/,
message: '请输入正确的邮箱格式',
},
},
{
label: '性别',
prop: 'gender',
component: {
name: 't-select',
options: [
{ label: '男', value: 'male' },
{ label: '女', value: 'female' },
],
},
},
],
// 表单属性
props: {
labelAlign: 'top', // 'left' | 'right' | 'top'
labelWidth: 'auto',
},
// 提交回调
onSubmit: async (data) => {
console.log('表单数据:', data);
},
};
// 提交表单
async function handleSubmit() {
try {
await formRef.value?.submit();
alert('提交成功!');
} catch (error) {
alert('表单验证失败!');
}
}
</script>
<template>
<MobileForm ref="formRef" :config="formConfig" />
<button @click="handleSubmit">提交</button>
</template>📖 配置说明
MobileFormConfig
表单的全局配置对象。
interface MobileFormConfig {
// 表单项列表
items?: MobileFormItem[];
// 初始表单数据
form?: Record<string, any>;
// 提交回调
onSubmit?: (data: Record<string, any>) => void | Promise<void>;
// 表单全局属性
props?: {
labelAlign?: 'left' | 'right' | 'top'; // 标签对齐方式
labelWidth?: string; // 标签宽度
};
// 是否在打开时重置表单
isReset?: boolean;
}MobileFormItem
表单项配置。
interface MobileFormItem {
// 字段名(必填)
prop: string;
// 标签文本
label?: string;
// 组件类型(向后兼容)
type?: 'picker' | 'date' | 'input' | 'switch' | 'rate' | 'stepper' | 'textarea' | 'radio' | 'checkbox' | 'slider' | 'upload';
// 自定义组件渲染(推荐)
component?: {
name: string; // 组件名称(如 't-input', 't-select')
props?: Record<string, any>; // 组件属性
options?: Array<{ label: string; value: any }>; // 选择器选项
};
// 选择器选项(也可以放在外层)
options?: Array<{ label: string; value: any }>;
// 是否必填
required?: boolean;
// 验证规则
rules?: {
pattern?: RegExp; // 正则表达式
validator?: (value: any) => boolean | string; // 自定义验证器
min?: number; // 最小长度
max?: number; // 最大长度
message?: string; // 错误消息
};
// 数据转换钩子
hook?: {
bind?: HookKey | HookFunction; // 绑定时转换
submit?: HookKey | HookFunction; // 提交时转换
};
// 默认值
value?: any;
// 是否隐藏
hidden?: boolean;
// 组件属性
props?: Record<string, any>;
}🎨 支持的组件类型
| 组件名称 | type 值 | 说明 |
|---------|---------|------|
| t-input | input | 输入框(默认) |
| t-textarea | textarea | 多行文本输入 |
| t-select | picker | 选择器(弹出选择) |
| t-date-picker | date | 日期选择器 |
| t-switch | switch | 开关 |
| t-rate | rate | 评分 |
| t-stepper | stepper | 步进器 |
| t-radio | radio | 单选框组 |
| t-checkbox | checkbox | 复选框组 |
| t-slider | slider | 滑块 |
| t-upload | upload | 上传 |
🔧 API 方法
通过 ref 可以调用以下方法:
const formRef = ref<MobileFormRef>();
// 验证表单
await formRef.value?.validate(); // Promise<boolean>
// 提交表单(会先验证)
await formRef.value?.submit(); // Promise<void>
// 重置表单
formRef.value?.reset();
// 清空表单
formRef.value?.clear();
// 获取表单数据
const data = formRef.value?.getForm(); // 返回所有数据
const value = formRef.value?.getForm('username'); // 获取指定字段
// 设置表单数据
formRef.value?.setForm('username', 'John');
// 更新选择器选项
formRef.value?.setOptions('gender', [
{ label: '男', value: 'male' },
{ label: '女', value: 'female' },
]);
// 动态设置表单配置
formRef.value?.setConfig({
labelAlign: 'left',
labelWidth: '100px',
});
// 显示/隐藏加载状态
formRef.value?.showLoading();
formRef.value?.hideLoading();
// 设置禁用状态
formRef.value?.setDisabled(true);
formRef.value?.setDisabled(false);📝 高级用法
1. 动态设置标签对齐
<script setup lang="ts">
import { ref } from 'vue';
import { MobileForm } from '@ai-low-form/tdesign-mobile-form';
const formRef = ref<MobileFormRef>();
function changeLabelAlign() {
formRef.value?.setConfig({ labelAlign: 'left' });
}
</script>
<template>
<button @click="changeLabelAlign">切换为左对齐</button>
<MobileForm ref="formRef" :config="formConfig" />
</template>2. 数据转换
const formConfig: MobileFormConfig = {
items: [
{
label: '年龄',
prop: 'age',
component: { name: 't-input' },
// 提交时转换为数字
hook: {
submit: 'number',
},
},
],
};3. 自定义验证
const formConfig: MobileFormConfig = {
items: [
{
label: '密码',
prop: 'password',
required: true,
rules: {
validator: (value) => {
if (value.length < 6) {
return '密码长度至少6位';
}
if (!/[A-Z]/.test(value)) {
return '密码必须包含大写字母';
}
return true;
},
},
},
],
};4. 万能插槽
<template>
<MobileForm :config="formConfig">
<!-- 自定义昵称输入框 -->
<template #slot-nickname-input="{ scope }">
<t-input
v-model="scope.nickname"
placeholder="请输入昵称"
clearable
/>
</template>
</MobileForm>
</template>🌟 完整示例
<script setup lang="ts">
import { ref } from 'vue';
import { MobileForm } from '@ai-low-form/tdesign-mobile-form';
import type { MobileFormRef, MobileFormConfig } from '@ai-low-form/tdesign-mobile-form';
const formRef = ref<MobileFormRef>();
const formConfig: MobileFormConfig = {
items: [
{
label: '姓名',
prop: 'name',
required: true,
},
{
label: '手机号',
prop: 'phone',
component: {
name: 't-input',
props: {
type: 'tel',
maxlength: 11,
},
},
required: true,
rules: {
pattern: /^1[3-9]\d{9}$/,
message: '请输入正确的手机号',
},
},
{
label: '性别',
prop: 'gender',
component: {
name: 't-select',
options: [
{ label: '男', value: 'male' },
{ label: '女', value: 'female' },
],
},
},
{
label: '生日',
prop: 'birthday',
component: {
name: 't-date-picker',
},
},
{
label: '个人简介',
prop: 'bio',
component: {
name: 't-textarea',
props: {
maxlength: 200,
placeholder: '请介绍一下自己',
},
},
},
],
props: {
labelAlign: 'top',
},
onSubmit: async (data) => {
console.log('提交的数据:', data);
// 发送到服务器...
},
};
async function handleSubmit() {
try {
await formRef.value?.submit();
alert('提交成功!');
} catch (error) {
console.error('验证失败:', error);
}
}
</script>
<template>
<div class="container">
<h1>用户信息</h1>
<MobileForm ref="formRef" :config="formConfig" />
<button @click="handleSubmit">提交</button>
</div>
</template>📄 License
MIT
🤝 贡献
欢迎提交 Issue 和 Pull Request!
