@qingbing/ts-v3-xz-form
v2.0.45
Published
以 vue3 + element-plus 为基础封装的 form 表单组件
Downloads
48
Maintainers
Readme
XzForm 插件介绍
1. 概要说明
1.1 地址
- 源代码: https://gitee.com/duqingbing/ts-v3-package/tree/ts-v3-xz-form
- 参考网址: https://element-plus.org/zh-CN/component/overview.html
1.2 插件描述
以 vue3 + element-plus 为基础封装的 form 表单组件
1.3 重要依赖
- @element-plus/icons-vue: ^2.3.1
- @qingbing/ts-v3-utils: ^1.0.1
- @qingbing/ts-v3-xz-editor: ^1.0.1
- @qingbing/ts-v3-element-plus: ^2.1.3
- @qingbing/ts-v3-json-editor: ^2.1.6
- @qingbing/ts-v3-md-editor: ^2.0.4
- axios: ^1.6.8
- element-plus: ^2.6.3
- vue: ^3.4.21
1.4 插件安装
# yarn 安装
yarn add @qingbing/ts-v3-xz-form
# npm 安装
npm i @qingbing/ts-v3-xz-form
2. 包说明
2.1 属性说明
该包主要封装了 vue3 下表单组件的使用, 重要提供以下五个属性参数
| 属性名 | 类型 | 是否必需 | 默认值 | 意义 | | :--------- | :-------------------------- | :------- | :----- | :----------------- | | isForm | boolean | 否 | true | 是否作为表单来处理 | | items | Record<string, TXzFormItem> | 是 | - | 传递的字段结果集 | | formData | TRecord | 是 | - | 表单操作数据 | | viewFields | string[] | 是 | [] | 信息展示字段 | | showFields | string[] | 是 | [] | form编辑字段 |
该组件的特殊之处, 在于不需要自己手动构建以上后续的四个参数, 组件提供了一个针对组件参数的工具,使用和理解该工具的配置,该组件也就没有难点了。
2.2 事件说明
| 事件名 | 类型 | 意义 | | :----- | :--- | :--- | | - | 无 | - |
2.3 实例暴露说明
| 属性名 | 类型 | | :----- | :--- | | - | 无 |
3. 配置工具介绍
3.1 组件工具的引入和基础使用
import { XzFormItemParse } from '@qingbing/ts-v3-xz-form'
const { items, viewFields, showFields, formData, rules } = XzFormItemParse.instance([
{
input_type: "text-view",
field: "uid",
default: "11",
label: "UID",
rules: [{ type: "required" }],
},
{
input_type: "input-text",
field: "username",
default: "",
label: "用户名",
rules: [{ required: true, type: "username" }],
}
])
.setViewFields(['username']) // 设置展示字段,设置后的字段,无论设置的 输入类型 如何, 得到的结果就是采取较好的方式提供用户浏览
.setShowFields(['async_remote']) // 表单显示字段, 不设置显示全部
.done() // 解析完毕得到结果
3.2 工具入口原型
如果向了解具体的 验证规则解析,参考 XzFormRuleParse 即可, 这里不赘述。
export declare class XzFormItemParse {
/**
* 获取字段处理实例
* @param items 表单配置项目
* @param formData 字段默认赋值
* @returns XzFormItemParse
*/
static instance(items: TXzFormItem[], formData?: TRecord): XzFormItemParse;
/**
* @param fields 展示字段集合
* @returns XzFormItemParse
*/
setViewFields(fields: string[]): XzFormItemParse;
/**
* @param fields 表单显示字段, 不设置显示全部
* @returns XzFormItemParse
*/
setShowFields(fields: string[]): XzFormItemParse;
/**
* 解析字段及规则信息并返回
*
* @returns { items, viewFields, showFields, formData, rules }
*/
done(): {
items: TXzFormItem[];
viewFields: string[];
showFields: string[];
formData: TRecord;
rules: Record<string, FormItemRule[]>;
};
}
3.3 工具使用主要掌握以下配置规则即可
3.3.1 配置规则原型
import type { TObject, TRecord } from '@qingbing/ts-v3-utils'
import type { FormItemRule, UploadRequestOptions } from 'element-plus'
import type { RuleType, SyncValidateResult, Value } from 'async-validator'
export type TXzFormOptions = {
name: string
}
// 支持的表单输入方式
export type TXzFormInputType =
| 'text-view' // 文本显示
| 'input-text' // 文本框编辑
| 'input-password' // 密码框编辑
| 'input-area' // 文本域编辑
| 'input-number' // 数字输入
| 'input-radio' // 单选按钮组
| 'input-checkbox' // 复选按钮组
| 'input-select' // 选择框
| 'switch' // 开关控制
| 'cascader' // 级联选择
| 'slider' // 滑块输入
| 'rate' // 评分
| 'color' // 取色器
| 'uploader' // 上传图片
| 'time-select' // 时间选择器
| 'time-picker' // 时间选择器
| 'date-picker' // 日期选择器
| 'auto-complete' // 自动补全输入
| 'json-editor' // json-editor
| 'md-editor' // md-editor
| 'content-editor' // text-editor
// 表单验证类型扩展
export type TXzFormRuleItem = Omit<FormItemRule, 'type'> & {
type?:
| RuleType
| 'required'
| 'id-card' // 身份证号
| 'qq' // qq
| 'username' // 用户名
| 'password' // 密码
| 'zipcode' // 邮编
| 'mobile' // 手机
| 'phone' // 座机
| 'contact' // 联系人(手机 | 座机)
| 'fax' // 传真
| 'ipv4' // ipv4 地址
| 'color' // 颜色值
| 'rate' // 评分
| 'slider' // 滑块
| 'switch' // 开关
| 'confirm' // 确认
| 'callback' // 回调函数
fullField?: string // bug for element-plus
params?: TObject // 回调或后端请求时携带的额外参数
callback?: TXzFormCallback // 同步回调函数,配合 type == callback 使用
asyncCallback?: TXzFormAsyncCallback // 异步回调函数,配合 type == callback 使用, 异步和同步可以同时使用,不建议
}
// 表单项目的配置字段配置类型
export type TXzFormItem = {
field: string // 操作字段
label: string // 显示标签
default?: any // 默认值
input_type: TXzFormInputType // 表单输入类型
exts?: TRecord // 额外参数
rules?: TXzFormRuleItem[] // 规则
}
/**
* 项目中的 option 选项类型
*/
export type TXzFormInputOption = {
id?: any,
value: PropertyKey,
label: string
}
/**
* 异步验证回调函数
*/
export type TXzFormAsyncCallback = (
callback: (error?: string | Error) => void,
value: unknown,
formData: TRecord,
params: TRecord
) => void | Promise<void>
/**
* 同步验证回调函数
*/
export type TXzFormCallback = (
callback: (error?: string | Error) => void,
value: Value,
formData: TRecord,
params: TRecord
) => SyncValidateResult | void
/**
* select 远端搜索并获取选项卡的函数类型
*/
export type TXzFormRemoteOption = (
params: TRecord,
formData: TRecord,
callback: ((ops: TXzFormInputOption[]) => void)
) => void
/**
* 自定义上传的函数类型
*/
export type TXzFormCustomUpload = (
options: UploadRequestOptions,
formData: TRecord,
callback: {
success: (fileUrl: string, message?: string) => void,
failure: (message: string) => void,
}
) => void
3.4.1 TXzFormItem 属性说明
| key | 类型 | 必须 | 意义 | | :--------- | :---------------- | :--- | :----------- | | field | string | 是 | 操作字段 | | label | string | 是 | 显示标签 | | default | any | 否 | 默认值 | | input_type | TXzFormInputType | 是 | 表单输入类型 | | exts | TRecord | 否 | 额外参数 | | rules | TXzFormRuleItem[] | 否 | 规则 |
3.4.2 TXzFormItem.input_type 说明
| 值 | 类型 | | :------------- | :----------- | | text-view | 文本显示 | | input-text | 文本框编辑 | | input-password | 密码框编辑 | | input-area | 文本域编辑 | | input-number | 数字输入 | | input-radio | 单选按钮组 | | input-checkbox | 复选按钮组 | | input-select | 选择框 | | switch | 开关控制 | | cascader | 级联选择 | | slider | 滑块输入 | | rate | 评分 | | color | 取色器 | | uploader | 上传图片 | | time-select | 时间选择器 | | time-picker | 时间选择器 | | date-picker | 日期选择器 | | auto-complete | 自动补全输入 | | json-editor | json-editor | | md-editor | md-editor | | content-editor | text-editor |
3.4.3 TXzFormItem.rules(TXzFormRuleItem[]) 说明
规则参考
async-validator.RuleItem
, 这里介绍下增加或不同的内容
| 值 | 类型 | 必填 | 说明 |
| :------------ | :------------------- | :--- | :--------------------------------------------------------------------------------------- |
| type | string | 否 | 支持原有的所有类型,同时还提供几种扩展类型 |
| fullField | string | 否 | 该字段不算新增,卡bug,验证不过时的字段替换位置,不设置使用 TXzFormItem.label
字段顶替 |
| params | TObject | 否 | 回调或后端请求时携带的额外参数 |
| callback | TXzFormCallback | 否 | 同步回调函数,配合 type == callback 使用 |
| asyncCallback | TXzFormAsyncCallback | 否 | 异步回调函数,配合 type == callback 使用 |
callback 和 asyncCallback 可以同时使用,不建议
3.4.3 TXzFormItem.rules(TXzFormRuleItem[]).type 说明
组件支持所有原有的类型,同时扩展如下几种常用验证
| 值 | 类型 |
| :------- | :---------------------------------------------- |
| required | 必填,不必须的,常规可使用 rule.required=true
|
| id-card | 身份证号 |
| qq | qq |
| username | 用户名 |
| password | 密码 |
| zipcode | 邮编 |
| mobile | 手机 |
| phone | 座机 |
| contact | 联系人(手机,座机) |
| fax | 传真 |
| ipv4 | ipv4 地址 |
| color | 颜色值 |
| rate | 评分 |
| slider | 滑块 |
| switch | 开关 |
| confirm | 确认 |
| callback | 回调函数 |
3.4.4 TXzFormItem.exts 说明
该参数主要提供了不同规则、不同输入类型的个性化属性,全部罗列在了该字段里面 对于输入参数,提供了 element-plus 官网组件属性中个人觉得有用的大部分属性 具体配置可参考底部示例, 提供几个组件参数配置地址参考:
json-editor: @qingbing/ts-v3-json-editor md-editor: @qingbing/ts-v3-md-editor content-editor: @qingbing/ts-v3-xz-editor
对于 element-plus 封装的表单项, 以
switch
为例: 属性参考网址内部规则代码如下: (ps: 其他element-plus 组件的规则解析类似,不再赘述)
const binding: TRecord = {}
binding.size = getExtData<string>('size', 'default')
binding.activeText = getExtData<string>('active-text', '')
binding.inactiveText = getExtData<string>('inactive-text', '')
const fileType = typeof props.formData[props.item.field]
// active-value 处理
let activeValue = getExtData<string | number | boolean | undefined>('active-value', undefined)
if (activeValue === undefined) {
switch (fileType) {
case "string":
activeValue = "1"
break;
case "number":
activeValue = 1
break;
default:
activeValue = true
break;
}
}
binding.activeValue = activeValue
// inactive-value 处理
let inactiveValue = getExtData<string | number | boolean | undefined>('inactive-value', undefined)
if (inactiveValue === undefined) {
switch (fileType) {
case "string":
inactiveValue = "0"
break;
case "number":
inactiveValue = 0
break;
default:
inactiveValue = false
break;
}
}
binding.inactiveValue = inactiveValue
const width = getExtData<string | number | false>('width', false)
false !== width && (binding.width = width)
const activeIcon = getExtData<string | Component | false>('active-icon', false)
false !== activeIcon && (binding.activeIcon = activeIcon)
const inactiveIcon = getExtData<string | Component | false>('inactive-icon', false)
false !== inactiveIcon && (binding.inactiveIcon = inactiveIcon)
if (props.isText) {
binding.disabled = true
} else {
binding.disabled = getExtData<boolean>('disabled', false)
}
4. item 生成工具
提供 快速生成大多数 form-item 的工具 XzFormItemMachine, 基础的类型验证以包含, 额外的演奏需要自行 mixins. 使用示例如下
import { XzFormItemMachine } from '@qingbing/ts-v3-xz-form'
const items= {
uid: mixins(XzFormItemMachine('textView', 'id', 'UID')),
nickname: mixins(XzFormItemMachine('text', 'nickname', '用户昵称'), {
rules: [{ type: "required" }],
}),
}
5. 示例
5.1 建议全局注册验证提示的中文包,不注册也不影响组件使用,那样每个规则最好都带上 message 就好
// main.ts
import '@qingbing/ts-v3-xz-form/dist/messages'
5.2 全局注册使用
- 一旦注册,
XzForm
作为组件全局通用 - 使用方法参考 4.2 模板组件使用, 去掉组件导入的语句即可
- 如果可以,建议全局安装并注册使用 @element-plus/icons-vue, 测试过程中组件手动引入时报错(或者全局注册下 Plus 组件即可,组件只在 uploader 时使用了该组件, 如果不使用 uploader 输入不注册也可)
- 对于样式的处理,md-editor 和 wangeditor 的样式比较大,最好按需导入, 如果不会使用到,建议不 import 到项目中
// main.ts
// icon 全导入并注册
// import * as ElementPlusIconsVue from '@element-plus/icons-vue'
// for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
// app.component(key, component)
// }
// icon 导入并注册 Plus 插件
// import { Plus } from '@element-plus/icons-vue'
// app.component('Plus', Plus)
// 导入表单组件
import '@qingbing/ts-v3-xz-form/dist/style.css'
import { XzFormPlugin } from '@qingbing/ts-v3-xz-form'
app.use(XzFormPlugin, {
name: 'XzForm',
options: {}
})
3.2 模板组件使用
<template>
<el-form ref="refForm" :model="formData" :rules="rules" label-width="160px">
<XzForm :isForm="isForm" :items="items" :formData="formData" :viewFields="viewFields" :showFields="showFields" />
<el-form-item>
<el-button type="primary" @click="submitForm(refForm)">Create </el-button>
<el-button @click="resetForm(refForm)">Reset</el-button>
</el-form-item>
</el-form>
<el-row>
<el-col :span="8" style="border-right: 1px solid #ccc;">
<p>items</p>
<pre><code>{{ items }}</code></pre>
</el-col>
<el-col :span="8" style="border-right: 1px solid #ccc;">
<p>rules</p>
<pre><code>{{ rules }}</code></pre>
</el-col>
<el-col :span="8">
<p>formData</p>
<pre><code>{{ formData }}</code></pre>
</el-col>
</el-row>
</template>
<script lang="ts" setup>
import 'md-editor-v3/lib/style.css'; // md-editor 编辑器样式
import 'md-editor-v3/lib/preview.css'; // md-editor 编辑器预览样式
import '@wangeditor/editor/dist/css/style.css' // wangeditor 样式表
import "@qingbing/ts-v3-xz-editor/dist/css/preview.css" // xz-editor 组件定义的一套编辑器基础样式
import '@qingbing/ts-v3-xz-form/dist/style.css' // xz-form 组件样式(整合了 json-editor 和 xz-editor 组件样式)
import type { FormInstance, UploadRawFile } from 'element-plus'
import type { TRecord } from "@qingbing/ts-v3-utils";
import type { TXzFormRemoteOption, TXzFormCustomUpload, TXzFormItem } from "@qingbing/ts-v3-xz-form";
import { XzForm, XzFormItemParse, XzFormItemMachine } from "@qingbing/ts-v3-xz-form";
import { mixins } from "@qingbing/ts-v3-utils";
import { ref } from 'vue'
import request from "axios";
const isForm = ref(true)
const refForm = ref<FormInstance>()
const submitForm = (form: FormInstance | undefined) => {
if (!form) { return }
form.validate((valid) => {
if (valid) {
console.log('哦业,验证都通过了!')
} else {
console.log('哎呀,验证到有错误呢!')
return false
}
})
}
const resetForm = (form: FormInstance | undefined) => {
if (!form) { return }
form.resetFields()
}
const fetchRemote = (data?: TRecord) => {
return request.create({
baseURL: 'http://mock.qiyezhu.net/mock/64e35b8e4a2b7b001dd2e4ec/example/ajax-test', // 默认就是 "/",
timeout: 5000, // 5000毫秒,5秒
headers: {
'Content-Type': 'application/json;charset=utf-8'
}
}).post('/', data ?? {})
}
const remoteFunc: TXzFormRemoteOption = (params, _, cb) => {
request.create({
baseURL: 'http://mock.qiyezhu.net/mock/64e35b8e4a2b7b001dd2e4ec/example/select-options',
timeout: 5000, // 5000毫秒,5秒
headers: {
'Content-Type': 'application/json;charset=utf-8'
}
})
.post('/', params)
.then(res => {
cb(res.data.data)
})
.catch(err => err)
}
const customUpload: TXzFormCustomUpload = (options, data: TRecord, callback) => {
const form = new FormData();
form.append('file', options.file);
form.append('name', 'qingbing');
request.post('http://mock.qiyezhu.net/mock/64e35b8e4a2b7b001dd2e4ec/example/upload-avatar', form)
.then(res => {
callback.success(res.data.data.url, "ok")
}).catch(err => callback.success(err.message))
}
const { items, viewFields, showFields, formData, rules } = XzFormItemParse.instance([
{
input_type: "text-view",
field: "uid",
default: "11",
label: "UID",
rules: [{ type: "required" }],
},
{
input_type: "auto-complete",
field: "suggestion",
default: "",
label: "建议输入",
exts: {
fetchSuggestions: (keyword: string, cb: (arg: any) => void) => {
console.log(keyword);
request.create({
baseURL: 'http://mock.qiyezhu.net/mock/64e35b8e4a2b7b001dd2e4ec/example/fetch-suggestion',
timeout: 5000, // 5000毫秒,5秒
headers: {
'Content-Type': 'application/json;charset=utf-8'
}
})
.post('/', { keyword, })
.then(res => {
cb(res.data.data)
})
.catch(err => err)
}
},
},
{
input_type: "input-select",
field: "remote",
default: "",
label: "UID",
exts: {
remoteMethod: remoteFunc
},
},
{
input_type: "input-text",
field: "username",
default: "",
label: "用户名",
rules: [{ required: true, type: "username" }],
},
{
input_type: "input-text",
field: "nickname",
default: "",
label: "昵称",
rules: [{ type: "required" }],
},
{
input_type: "input-text",
field: "email",
default: "",
label: "邮箱",
rules: [{ required: true, type: "email" }],
},
{
input_type: "input-text",
field: "id_card",
default: "",
label: "身份证",
rules: [{ required: true, type: "id-card" }],
},
{
input_type: "input-text",
field: "qq",
default: "",
label: "QQ",
rules: [{ required: true, type: "qq" }],
},
{
input_type: "input-text",
field: "zipcode",
default: "",
label: "邮编",
rules: [{ required: true, type: "zipcode" }],
},
{
input_type: "input-text",
field: "mobile",
default: "",
label: "手机",
rules: [{ required: true, type: "mobile" }],
},
{
input_type: "input-text",
field: "phone",
default: "",
label: "座机",
rules: [{ required: true, type: "phone" }],
},
{
input_type: "input-text",
field: "contact",
default: "",
label: "联系人",
rules: [{ required: true, type: "contact" }],
},
{
input_type: "input-text",
field: "fax",
default: "",
label: "传真",
rules: [{ required: true, type: "fax" }],
},
{
input_type: "input-text",
field: "ipv4",
default: "",
label: "ipv4 地址",
rules: [{ required: true, type: "ipv4" }],
},
{
input_type: "color",
field: "color",
default: "",
label: "颜色",
rules: [{ required: true, type: "color" }],
},
{
input_type: "rate",
field: "rate",
default: 0,
label: "评分",
rules: [{ required: true, type: "rate" }],
},
{
input_type: "slider",
field: "slider",
default: '',
label: "滑块",
exts: {
min: 0,
max: 10
},
rules: [{ required: true, type: "slider" }],
},
{
input_type: "switch",
field: "switch",
default: 1,
label: "开关",
rules: [{ required: true, type: "switch" }],
exts: {
'inactiveValue': 0,
'activeValue': 1,
}
},
{
input_type: "input-area",
field: "info",
default: "",
label: "个人简介",
rules: [{ type: "required" }],
},
{
input_type: "input-number",
field: "age",
default: 0,
label: "年龄",
exts: {
min: 0,
max: 127
},
rules: [{ type: "number", required: true }],
},
{
input_type: "input-radio",
field: "fav_fruit",
default: "banana",
label: "最爱水果",
exts: {
options: [
{ value: "apple", label: "苹果" },
{ value: "pear", label: "梨子" },
{ value: "banana", label: "香蕉" },
{ value: "pomegranate", label: "石榴" },
{ value: "persimmon", label: "柿子" },
]
},
rules: [{ required: true, type: "enum" }],
},
{
input_type: "input-checkbox",
field: "like_fruit",
default: ["apple", "banana"],
label: "喜欢水果",
exts: {
min: 2,
max: 4,
options: [
{ value: "apple", label: "苹果" },
{ value: "pear", label: "梨子" },
{ value: "banana", label: "香蕉" },
{ value: "pomegranate", label: "石榴" },
{ value: "persimmon", label: "柿子" },
]
},
rules: [{ required: true, type: "array" }],
},
{
input_type: "input-select",
field: "sex",
default: "2",
label: "性别",
exts: {
min: 2,
max: 4,
options: [
{ value: "1", label: "秘密" },
{ value: "2", label: "男生" },
{ value: "3", label: "女生" },
]
},
rules: [{ required: true, type: "enum" }],
},
{
input_type: "input-select",
field: "hobby",
default: ["sing", "run"],
label: "爱好",
exts: {
min: 2,
max: 3,
multiple: true,
options: [
{ value: "dance", label: "跳舞" },
{ value: "sing", label: "唱歌" },
{ value: "run", label: "跑步" },
{ value: "listen", label: "听歌" },
]
},
rules: [{ required: true, type: "array" }],
},
{
input_type: "md-editor",
field: "md-editor",
default: "# hello\n```php\n$a = 5;\n$b = 5;\n$c = $a + $b\n```\n",
label: "Md编辑",
exts: {
conf: {
mode: "mini"
}
},
},
{
input_type: "json-editor",
field: "json-editor",
default: '{"a":10, "b":10}',
label: "Json Editor",
exts: {
options: {
mode: "text"
},
height: 200
},
},
{
input_type: "content-editor",
field: "information",
default: '<p>我的爱好黑多</p><blockquote>test</blockquote>',
label: "个人简介",
exts: {
showHtml: true,
height: "300px"
},
},
{
input_type: "cascader",
field: "cascader",
default: ["510000", "511600", "511623"],
label: "Content Editor",
exts: {
options: [
{
value: '110000',
label: '北京市',
children: [
{
value: '110101',
label: '东城区'
},
{
value: '110102',
label: '西城区'
}
]
},
{
value: '510000',
label: '四川省',
children: [
{
value: '510100',
label: '成都市',
children: [
{
value: '510104',
label: '锦江区'
},
{
value: '510105',
label: '青羊区'
}
]
},
{
value: '510300',
label: '自贡市',
children: [
{
value: '510302',
label: '自流井区'
},
{
value: '510303',
label: '贡井区'
}
]
},
{
value: '511600',
label: '广安市',
children: [
{
value: '511602',
label: '广安区'
},
{
value: '511623',
label: '邻水县'
},
{
value: '511681',
label: '华蓥市'
}
]
},
{
value: '511700',
label: '达州市',
children: [
{
value: '511702',
label: '通川区'
},
{
value: '511703',
label: '达川区'
}
]
}
]
},
{
value: '130000',
label: '河北省',
children: [
{
value: '130100',
label: '石家庄市',
children: [
{
value: '130102',
label: '长安区'
},
{
value: '130104',
label: '桥西区'
}
]
},
{
value: '130300',
label: '秦皇岛市',
children: [
{
value: '130302',
label: '海港区'
}
]
}
]
}
],
},
},
{
input_type: "uploader",
field: "avatar",
default: '',
label: "头像",
exts: {
class: "avatar-upload",
action: "/personal/upload-avatar",
name: "file", // 上传的文件字段名
autoUpload: true, // 是否在选取文件后立即进行上传
withCredentials: true, // 支持发送 cookie 凭证信息
headers: {}, // 文件头
data: {}, // 上传时附带的参数
accept: "image/png, image/jpeg", // 接受上传的文件类型
// 上传前检查
beforeUpload: (rawFile: UploadRawFile) => {
if (rawFile.type !== 'image/png' && rawFile.type !== 'image/jpeg') {
alert('上传头像图片只能是 JPG 或 PNG 格式!')
return false
} else if (rawFile.size / 1024 / 1024 > 2) {
alert('上传头像图片大小不能超过 2MB!')
return false
}
return true;
},
customUpload: customUpload,
},
},
{
input_type: "date-picker",
field: "year",
default: '',
label: "年份",
exts: {
type: 'year',
},
},
{
input_type: "date-picker",
field: "years",
default: '',
label: "年份(多)",
exts: {
type: 'years',
},
},
{
input_type: "date-picker",
field: "month",
default: '',
label: "月份",
exts: {
type: 'month',
},
},
{
input_type: "date-picker",
field: "monthrange",
default: '',
label: "月份范围",
exts: {
type: 'monthrange',
},
},
{
input_type: "date-picker",
field: "daterange",
default: '',
label: "日期范围",
exts: {
type: 'daterange',
},
},
{
input_type: "date-picker",
field: "datetime",
default: '',
label: "时间",
exts: {
type: 'datetime',
},
},
{
input_type: "date-picker",
field: "datetimerange",
default: '',
label: "时间范围",
exts: {
type: 'datetimerange',
},
},
{
input_type: "date-picker",
field: "week",
default: '',
label: "周",
exts: {
type: 'week',
},
},
{
input_type: "date-picker",
field: "dates",
default: '',
label: "日期(多)",
exts: {
type: 'dates',
},
},
{
input_type: "date-picker",
field: "date",
default: '',
label: "日期",
exts: {
type: 'date',
},
},
{
input_type: "date-picker",
field: "past_date",
default: '',
label: "以往日期",
exts: {
type: 'date',
'disabledDate': 'future',
},
},
{
input_type: "date-picker",
field: "future_date",
default: '',
label: "往后日期",
exts: {
type: 'date',
'disabledDate': 'past',
},
},
{
input_type: "time-picker",
field: "time",
default: '',
label: "选择时间1",
exts: {},
},
{
input_type: "time-picker",
field: "timerange",
default: '',
label: "时间范围2",
exts: {
'is-range': true, // 是否时间范围
},
},
{
input_type: "time-select",
field: "time_select1",
default: '',
label: "时间选择3",
exts: {
},
},
{
input_type: "input-password",
field: "new_password",
default: "",
label: "新密码",
rules: [{ required: true, type: "password" }],
},
{
input_type: "input-password",
field: "confirm_password",
default: "",
label: "确认密码",
rules: [
// { required: true, type: "password" },
{ required: true, type: "confirm", message: "确认密码和上次密码不同" }
],
exts: {
field: 'new_password',
value: 'admin' // field 存在时, field 优先
}
},
{
input_type: "input-text",
field: "callback",
default: "",
label: "同步回调",
exts: {
params: {
name: "qingbing"
}
},
rules: [
{
required: true, type: "callback", trigger: 'blur', callback: <TXzFormCallback>(
callback: (error?: string | Error) => void,
value: unknown,
formData: TRecord,
params: TRecord
) => {
console.log(value);
console.log(formData);
console.log(params);
/**
* validator 为同步验证,验证失败方式
* 1. return false
* 2. 调用 callback(), 除了不给参数,其它都是失败
* 1. 如果设置了 message, 提示为 message
* 2. 没有message时, callback 参数不为空就以参数为提示,否则为 "{FullField} fails"
*/
// 成功
// return true
// callback()
// 失败
callback("错误提示1")
// callback(new Error("错误提示2"))
// return false
},
}
],
},
{
input_type: "input-text",
field: "async_callback",
default: "",
label: "异步回调",
rules: [
{
required: true, type: "callback", trigger: 'blur', asyncCallback: <TXzFormCallback>(
callback: (error?: string | Error) => void,
value: unknown,
formData: TRecord,
params: TRecord
) => {
console.log(value);
console.log(formData);
console.log(params);
/**
* 异步验证,返回方式只能使用 callback 调用方式
* 成功: callback()
* 失败: callback('error message'); callback(new Error('error message'))
*/
// 成功
// callback()
// 失败
// callback('error message')
callback(new Error('error - message'))
},
}
],
},
{
input_type: "input-text",
field: "custom_async",
default: "",
label: "自定义异步",
rules: [
{
required: true, trigger: 'blur', asyncValidator(rule, value, callback, source, options) {
return new Promise((resolve, reject) => {
// resolve() // "哦业,验证成功了"
reject("哎呀,验证有误呢")
})
},
}
],
},
{
input_type: "input-text",
field: "async_remote",
default: "",
label: "Ajax 远端回调",
rules: [
{
required: true, type: "callback", trigger: 'blur', asyncCallback: <TXzFormCallback>(
callback: (error?: string | Error) => void,
value: unknown,
formData: TRecord,
params: TRecord
) => {
fetchRemote(params)
.then((res) => {
if (res.data.code == 0) {
callback() // 成功
} else {
callback(res.data.msg) // 失败
}
})
.catch(err => callback(err));
},
}
],
},
])
.setViewFields(['username', 'nickname'])
// .setShowFields(['async_remote', 'custom_async', 'time_select1'])
.done()
const resetPasswordItems: Record<string, TXzFormItem> = {
oldPassword: mixins(XzFormItemMachine('password', 'oldPassword', '原始密码'), {
rules: [{ required: true }]
}),
newPassword: mixins(XzFormItemMachine('password', 'newPassword', '新 密 码'), {
rules: [{ required: true }]
}),
confirmPassword: mixins(XzFormItemMachine('password', 'confirmPassword', '确认密码'), {
rules: [
{ required: true },
{ type: "confirm", message: "两次秘密输入不一致" }
],
exts: {
field: 'newPassword'
}
}),
}
// const { items, viewFields, showFields, formData, rules } = XzFormItemParse.instance(resetPasswordItems)
// .done()
</script>