@qynpm/form
v1.0.2
Published
基于 Vue 3 和 Element Plus 的 schema 表单工具包。
Downloads
281
Readme
@qynpm/form
基于 Vue 3 + Element Plus 的 schema 驱动表单工具包。
当前提供:
useFormItemuseSaveuseSyncQueryParams
安装
pnpm add @qynpm/formPeer Dependencies:
vue >= 3.4element-plus >= 2.0@element-plus/icons-vue >= 2.0pinia >= 2.0vue-router >= 4.0@qynpm/ui >= 1.0.0
引入
这是一个以 hooks 为主的工具包,通常按需引入即可:
import { useFormItem, useSave, useSyncQueryParams } from '@qynpm/form'设计说明
useFormItem 采用 schema 驱动模式:
- 第一参数
model用来描述字段结构、默认值、控件类型和渲染方式 - 第二参数
options用来描述 query 同步、缓存、紧凑布局、保存能力等 - 内部维护响应式
modelForm - 页面侧通过
formItem/formItems输出表单项 - 提交时通过
modelForm或getModelForm()获取当前值
补充说明:
QyDialog现在通过@qynpm/ui提供,createInstance仍属于包内运行时实现- 当前版本更适合作为体系内拆包使用,还不是完全脱离宿主约定的通用表单库
- 图标能力仍然默认复用宿主现有方案
imageInput暂时仍然是过渡能力,后续可以继续拆成独立包
快速上手
<template>
<el-form v-bind="form.getFormProps()">
<component :is="form.formItem" prop="shopName" />
<component :is="form.formItem" prop="shopType" />
<el-form-item>
<el-button type="primary" @click="handleSubmit">提交</el-button>
<el-button @click="form.reset">重置</el-button>
</el-form-item>
</el-form>
</template>
<script setup lang="ts">
import { useFormItem } from '@qynpm/form'
const form = useFormItem(
[
{
label: '店铺名称',
key: 'shopName',
type: 'string',
rules: [{ required: true, message: '请输入店铺名称', trigger: 'blur' }]
},
{
label: '店铺类型',
key: 'shopType',
type: 'select',
value: 'erp',
options: [
{ label: 'ERP', value: 'erp' },
{ label: 'Production', value: 'production' }
]
}
],
{
id: 'shop-form'
}
)
function handleSubmit() {
console.log(form.getModelForm())
}
</script>API
useFormItem(model, options?)
model
类型:FormItemSet<Key>[]
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| label | string | 表单项标题 |
| key | string | 字段名,对应 modelForm 的 key |
| asKey | string | 没有 key 时的备用唯一标识 |
| type | 'string' \| 'number' \| 'imageInput' \| 'select' \| 'date' \| 'inputNumber' \| 'radio' \| 'qyMoneyInput' \| 'qyRemoteSelect' \| 'qyImageUpload' \| 'qyDatePicker' \| 'qyInputNumber' | 控件类型 |
| value | any | 默认值 |
| props | Record<string, any> | 透传给控件的 props |
| rules | FormItemRule[] | Element Plus 校验规则 |
| options | Array \| Ref | select / radio 选项 |
| render | Function | 自定义渲染函数 |
类型映射
@qynpm/form 保留旧 schema 类型,但内部基础组件已经切到 @qynpm/ui:
| schema 类型 | 默认组件 | 说明 |
| --- | --- | --- |
| string | QyInput | 普通文本输入,type="number" 仍按输入框字符串语义处理 |
| number | QyInput | 兼容旧 ElInput 用法,不等同于数字步进器 |
| select | QySelect | 保留旧 options: { ref, label, value } 映射和数字值转换 |
| radio | QyRadioGroup | 保留旧 options 映射,支持普通 radio 和 button radio |
| date | QyDatePicker | 保留 datetimerange 结束时间归一逻辑 |
| inputNumber | QyInputNumber | 普通数字输入,默认值仍为 0 |
| imageInput | QyRemarkImage | 备注文本 + 单图协议,走特殊适配路径 |
显式 qy* 类型只保留语义和旧基础类型明显不同的组件:
| schema 类型 | 默认组件 | 使用场景 |
| --- | --- | --- |
| qyMoneyInput | QyMoneyInput | 金额、费用、税费 |
| qyRemoteSelect | QyRemoteSelect | 远程筛选下拉 |
| qyImageUpload | QyImageUpload | 单图字段;配置 multiple 后用于财审凭证、付款凭证等多图数组 |
| qyDatePicker | QyDatePicker | 需要显式表达 UI 日期组件时使用 |
| qyInputNumber | QyInputNumber | 需要显式表达 UI 数字输入时使用 |
不再额外暴露 qyInput、qySelect、qyRadioGroup。对应能力已经分别收敛到 string、select、radio,避免 schema API 重复。
imageInput 暂不改名为 remarkImage。当前项目内仍存在老组件 @qiyin/components/remarkImage,而 @qynpm/ui 中也有 QyRemarkImage。为了避免出现第三套命名,form 继续使用旧 schema 名 imageInput 承接备注图文协议。
options
| 字段 | 类型 | 默认值 | 说明 |
| --- | --- | --- | --- |
| form | Record<string, any> | {} | 初始化表单值,会覆盖 schema 默认值 |
| syncQuery | boolean | false | 是否和 URL query 同步 |
| compact | boolean | false | 是否启用紧凑布局 class |
| cache | { key: string } | undefined | 启用 localStorage 缓存 |
| customSetterGetter | Record<string, CustomSetterGetter> | {} | query 同步时的自定义序列化 / 反序列化 |
| showFilter | boolean | true | useSave 是否展示快捷筛选项 |
| id | string | undefined | useSave 使用的唯一标识 |
返回值
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| model | FormItemSet[] | 原始 schema |
| modelForm | Reactive<Record<string, any>> | 响应式表单值对象 |
| formProps | ComputedRef | 表单 props 计算结果 |
| getModelForm() | () => Record<string, any> | 获取当前表单值快照 |
| formItem() | ({ prop \| itemKey }) => VNode | 渲染单个表单项 |
| formItems() | (props) => VNode[] | 批量渲染表单项,支持 includes / excludes |
| reset() | () => void | 重置到默认值,并清理缓存 |
| getFormProps() | () => { model, rules } | 返回可直接绑定到 el-form 的 props |
| save() | (buttonProps?) => VNode \| null | 保存按钮 |
| apply() | (buttonProps?) => VNode \| null | 应用按钮 |
| SaveComponent() | () => JSX.Element | 保存 / 应用按钮组 |
| getFormItemVNode() | (item) => VNode | 获取单个表单项 VNode |
useSave(options)
用于保存和恢复表单条件:
import { useSave } from '@qynpm/form'
const { save, apply, SaveComponent } = useSave({
id: 'query-form',
modelForm,
showFilter: true
})useSyncQueryParams(queryParams, options?)
用于查询表单与地址栏联动:
const form = useFormItem(schema, {
syncQuery: true
})当前保持的行为包括:
- query 初始化回填
- 数组值默认序列化 / 反序列化
date时间区间转换- 尝试同步更新 tagsView 中的 query
使用示例
基础表单
<component :is="form.formItem" prop="shopName" />
<component :is="form.formItem" prop="shopType" />批量渲染
<component :is="form.formItems" />includes / excludes
<component :is="form.formItems" includes="keyword,status,channel" />
<component :is="form.formItems" excludes="remark" />query 表单
const queryForm = useFormItem(schema, {
syncQuery: true,
id: 'query-form'
})启用缓存
const form = useFormItem(schema, {
cache: {
key: 'shop-form-cache'
}
})自定义渲染
{
label: '自定义字段',
key: 'custom',
type: 'string',
render: (h, { modelForm, Component }) =>
h('div', { class: 'flex gap-2' }, [
Component,
h('span', modelForm.custom || '')
])
}保存 / 应用按钮
<template>
<component :is="form.SaveComponent" />
</template>样式与运行时说明
- 宿主项目需要引入
element-plus/dist/index.css @qynpm/form当前会自动注入包内样式- 宿主项目需要提供
@element-plus/icons-vue - 如果使用
syncQuery,宿主项目需要接入pinia和vue-router - 包内图标仍然默认复用宿主图标体系
imageInput默认使用/permission-api/common/uploads和Admin-Token,如宿主上传接口不同,需要显式传入api/tokenKey
本地开发
pnpm dev
pnpm buildpnpm dev:启动 playground 预览页pnpm build:构建到dist/
Workspace 联调:
{
"dependencies": {
"@qynpm/form": "workspace:*"
}
}已知限制
useFormItem和useSave目前仍然是配套关系,后续可以再评估是否继续拆开。createInstance仍在包内,后续可根据拆包策略决定是否继续下沉。- 当前图标能力仍然偏体系内约定。
imageInput是备注图文协议,默认上传接口只适合当前起印体系;跨项目使用时需要确认api/tokenKey。
当前联调说明
当前不再通过手动修改 form / ui 源码 import 来切换联调模式,而是统一使用顶层 Vite 开关控制。
开关位置:
qy-workspace顶层vite.config.ts
当前配置:
const ENABLE_LOCAL_QIYIN_DEBUG = true规则如下:
- 当值为
true时
@qiyin/form/@qynpm/form映射到本地源码入口 index.ts@qynpm/ui映射到本地源码入口 ../UI/lib/index.js- 适合 workspace 本地联调
- 当值为
false时
- 走各自包的正常入口
- 更接近线上/发包后的使用方式
注意:
- 修改开关后需要重启对应项目的 dev 服务
