# 万能表单

# 组件名:vk-data-form

# 核心思想:通过JSON配置渲染规则

如:渲染一个input输入框,只需要如下代码

{ key:"nickname", title:"昵称", type:"text" }
1

渲染一个单选框组,只需要如下代码

{
 key:"gender", title:"性别", type:"radio",
 data:[
   { value:1, label:"男" },
   { value:2, label:"女" }
 ]
}
1
2
3
4
5
6
7

# 你甚至还可以通过 表单可视化拖拽工具 直接生成vk框架代码 点击体验 (opens new window)

# 基础用法

vk-data-dialog为弹窗表单,去掉则为表单页面

<vk-data-dialog
  v-model="form1.props.show"
  title="表单标题"
  width="600px"
  mode="form"
>
  <vk-data-form
    ref="form1"
    v-model="form1.data"
    :action="form1.props.action"
    :columns="form1.props.columns"
    :rules="form1.props.rules"
    :form-type="form1.props.formType"
    :loading.sync="form1.props.loading"
    :auto-close="true"
    label-width="140px"
    @success="onFormSuccess"
  ></vk-data-form>
</vk-data-dialog>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

js部分

export default {
  data() {
    // 页面数据变量
    return {
      // 表单相关开始-----------------------------------------------------------
      form1: {
        // 表单请求数据,此处可以设置默认值
        data: {
          radio: 1,
          checkbox : [1,2]
        },
        // 表单属性
        props: {
          // 表单请求地址
          action: "template/test/sys/test",
          // 表单字段显示规则
          columns: [
            { key: "text", title: "text类型字段", type: "text" },
            { key: "number", title: "number类型字段", type: "number" },
            { 
              key: "radio", title: "radio类型字段", type: "radio",
              data: [
                { value: 1, label: "选项一" },
                { value: 2, label: "选项二" },
              ]
            },
            { 
              key: "checkbox", title: "checkbox类型字段", type: "checkbox",
              data: [
                { value: 1, label: "选项一" },
                { value: 2, label: "选项二" },
              ]
            },
            { key: "switch", title: "switch类型字段", type: "switch" }
          ],
          // 表单验证规则
          rules: {
            text: [
              { required: true, message: "text不能为空", trigger: "change" },
            ]
          },
          // add 代表添加 update 代表修改
          formType: "",
          // 表单是否在请求中
          loading: false,
          // 是否显示表单1 的弹窗
          show: false
        }
      },
      // 表单相关结束-----------------------------------------------------------
    };
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53

# 进阶用法

请直接看示例文件 /pages_template/components/form/form-pro

# API

# 属性

参数 说明 类型 默认值 可选值
v-model 表单数据源 Object {} -
rules 表单验证规则 查看规则 Object -
action 表单提交地址,支持:
1、vk框架下的云函数地址
2、http请求地址
3、自定义function请求模式
String、Function -
before-action action请求前拦截器 查看示例代码 Function -
is-request 是否是http请求模式 查看http请求模式 Boolean false true
form-type 表单类型,用于复用表单 查看表单复用 String -
columns 通用 - 字段规则 查看columns Array [] -
loading 表单是否在请求中 Boolean false true
label-width 左侧label宽度 String,Number "80px" -
width 表单宽度 Number,String -
footer-show 底部按钮是否显示 Boolean true false
footer-center 底部按钮是否居中 Boolean true false
show-cancel 是否显示取消按钮 Boolean true false
cancel-text 取消按钮的文字 String 关 闭 -
submit-text 确定按钮的文字 String 确 定 -
submit-disabled 确定按钮是否禁用 Boolean false true
auto-close 表单请求成功后自动关闭 Boolean true false
auto-reset 自动重置表单 String Boolean true
label-position 对齐方式 String right right left top
max-height 表单最大高度 String -
size 表单内组件的size String -
label-suffix label的后缀 String -
disabled 禁用表单 Boolean false true
clearable 表单内的组件有清空效果 Boolean true false
success-msg 表单提交成功后右上角的提示 String 操作成功! -
inline 是否设置整个表单为横向表单 Boolean false true
columns-number 横向表单每行显示数量 Number 2 -
need-alert 表单请求失败后,是否自动alert弹窗(若设为false,则可以通过监听fail事件自己处理错误) Boolean true false

# columns(字段渲染规则)

columns是一个数组,数组内每个元素有以下属性,每个元素代表一个表单元素

参数 说明 类型 默认值 可选值
key 字段名 查看 String - -
title 字段显示的名称 查看 String - -
type 组件类型 查看 String - -
width 宽度 查看 Number - -
placeholder 占位符 查看 String - -
tips 下方的提示 查看 String -
labelWidth 单独设置该字段的左侧label宽度,单位px 查看 Number - -
showLabel 是否显示左侧label文字 查看 Boolean true false
show 表单复用时的显示规则 查看 array - -
showRule 是否显示该字段 查看 String、Function - -
disabled 是否禁用 查看 Boolean、String、Function false true
watch 监听key对应的值的改变(只监听组件内部造成的值的改变) 查看 Function - -

# key(字段名)

字段名,如下方代码中,keynickname,代表绑定 nickname 字段

{ key: "nickname", title:"昵称", type:"text", },
1

# title(标题)

字段显示的名称,如下方代码中,title昵称,代表该字段以别名 昵称 显示在页面上。

{ key: "nickname", title:"昵称", type:"text", },
1

# type(组件类型)

页面需要渲染的组件类型,如下方代码中,typetext,在 万能表格 中渲染为 字符串,在 万能表单 中渲染为 input输入框

{ key: "nickname", title:"昵称", type:"text", },
1

# width(宽度)

单位是px,只能是数字,如下

{ key: "nickname", title:"昵称", type:"text", width: 200 },
1

# placeholder(占位符)

占位符,类似 input 组件中的 placeholder (即用户还未输入任何内容时输入框内的提示)

# tips(下方的固定提示)

下方的固定提示,与 placeholder 不同的是:不管用户是否输入信息,此提示一直都在。而 placeholder 是当用户输入内容后,提示就隐藏了。

tips支持解析html字符串,如下所示

// 增加详情按钮 跳新窗口打开新页面
{ key: "text1", title:"text类型字段", type:"text", tips:`<text>这里使其他文字介绍</text><a href="#/pages/order/list" target="_blank">详情</a>`, width:600 },
// 增加详情按钮 关闭当前页面,跳新页面
{ key: "text2", title:"text类型字段", type:"text", tips:`<text>这里使其他文字介绍</text><a href="javascript:void(0);" onClick="vk.navigateTo('/pages_template/components/form/form-basic');">详情</a>`, width:600 },
// 增加详情按钮 跳https外部页面
{ key: "text3", title:"text类型字段", type:"text", tips:`<text>这里使其他文字介绍</text><a href="https://www.baidu.com" target="_blank">跳百度</a>`, width:600 },
1
2
3
4
5
6

tips还支持解析对象数组,如下所示

{ 
  key:"text1", title:"选择快递公司", type:"text",
  tips:[
    { text:"查不到快递公司?" },
    {
      text:"点击添加",
      click:()=>{
        console.log(1)
      },
    },
    {
      text:"刷新",
      click:()=>{
        console.log(1)
      },
    }
  ]
},
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# labelWidth(单独设置label宽度)

默认在万能表单的属性上设置统一的labelWidth,如果在columns内设置了labelWidth,则此为准

# showLabel(是否显示label)

默认为true,当设置为false时,对应的title不显示。

# show(复用时的显示规则)

表单组件的组件 form-type 可以动态复用同一个表单达到显示不同字段的功能。

完整示例代码可以查看页面 pages_template/components/form/form-dialog-2

show 是一个字符串数组,columns 数组内每一个元素都可以单独设置 show

  • 如果 show 字段不存在,代表显示。
  • 如果 show 的某元素中包含 form-type的值,则代表显示。
  • 如果 show 的某元素中不包含 form-type的值,则不显示。

# showRule(自定义显示规则)

与 show 不同,showRule 更灵活。

如 当 login_appid_type = 1 时,渲染 mode 字段,否则不渲染(支持符号 ===>>=<<=!={in}{nin}&&||

提示:=== 效果一样

{
  key:"login_appid_type", title:"登录权限", type:"radio",
  optionType:"button",
  data:[
    { value:1, label:"部分应用" },
    { value:0, label:"全部应用" }
  ]
},
{
  key:"mode", title:"模式", type:"radio",
  optionType:"button",
  data:[
    { value:1, label:"覆盖" },
    { value:2, label:"新增" },
    { value:3, label:"移除" }
  ],
  showRule:"login_appid_type==1",
},
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

{in}和{nin}的用法

{ key:"arr", title:"arr", type:"array<string>" },
{ key:"text", title:"text", type:"text" },
{ key:"text1", title:"arr包含1则显示", type:"text", showRule:"arr{in}1" },
{ key:"text2", title:"arr不包含2则显示", type:"text", showRule:"arr{nin}2" },
1
2
3
4

同时 showRule 还支持函数形式

{
  key:"login_appid_type", title:"登录权限", type:"radio",
  optionType:"button",
  data:[
    { value:1, label:"部分应用" },
    { value:0, label:"全部应用" }
  ]
},
{
  key:"mode", title:"模式", type:"radio",
  optionType:"button",
  data:[
    { value:1, label:"覆盖" },
    { value:2, label:"新增" },
    { value:3, label:"移除" }
  ],
  showRule:(formData)=>{
    if(formData.login_appid_type == 1){
      return true;
    }else{
      return false;
    }
  }
},
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

# disabled(自定义禁用规则)

disabledshowRule 基本写法一致,功能区别是,showRule 是满足条件则显示,disabled 是满足条件则禁用。

如 当 login_appid_type = 0 时,禁用 mode 字段(支持符号 = == > >= < <= != in && || )

提示:= 和 == 效果一样

{
  key:"login_appid_type", title:"登录权限", type:"radio",
  optionType:"button",
  data:[
    { value:1, label:"部分应用" },
    { value:0, label:"全部应用" }
  ]
},
{
  key:"mode", title:"模式", type:"radio",
  optionType:"button",
  data:[
    { value:1, label:"覆盖" },
    { value:2, label:"新增" },
    { value:3, label:"移除" }
  ],
  disabled:"login_appid_type==0",
},
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

同时 disabled 还支持函数形式

{
  key:"login_appid_type", title:"登录权限", type:"radio",
  optionType:"button",
  data:[
    { value:1, label:"部分应用" },
    { value:0, label:"全部应用" }
  ]
},
{
  key:"mode", title:"模式", type:"radio",
  optionType:"button",
  data:[
    { value:1, label:"覆盖" },
    { value:2, label:"新增" },
    { value:3, label:"移除" }
  ],
  disabled:(formData)=>{
    if(formData.login_appid_type === 0){
      return true;
    }else{
      return false;
    }
  }
},
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

# watch(监听)

用于监听key对应的值的改变(只监听组件内部造成的值的改变)

使用示例如下:

{
  key: "text", title:"text类型字段", type:"text",
  watch: (res) => {
    console.log("watch", res)
  }
}
1
2
3
4
5
6

# inline(行内表单)

<vk-data-form
  ...其他组件
  :inline="true"
  :columnsNumber="2"
></vk-data-form>
1
2
3
4
5

行内表单中columns若设置oneLine:true可强制单独一行

columns:[
  { key: "text1", title:"text类型字段", type:"text" },
  { key: "text2", title:"text类型字段", type:"text" },
  { key: "text3", title:"text类型字段", type:"text", oneLine:true }, // 单独一行
  { key: "text4", title:"text类型字段", type:"text", oneLine:true, width: 500 }, // 单独一行,并设置input的宽度
]
1
2
3
4
5
6

# type(组件类型)

type类型(更多请见:/pages_template/components/form/form-pro

form1:{
  // 表单请求数据,此处可以设置默认值
  data: {
    
  },
  // 表单属性
  props:[
    { key:"", title:"基础字段", type:"bar-title" },
    { key:"text", title:"单行文本", type:"text" },
    {
      key:"textarea", title:"多行文本", type:"textarea",
      autosize:{ minRows:4, maxRows:10 },
      maxlength:200,
      showWordLimit:true,
    },
    { key:"money", title:"money类型", type:"money", tips:"100 = 1元。页面显示的是1,实际的值是100,请看右上角表单数据的值。" },
    { key:"number", title:"number类型", type:"number", precision:2, tips:"number类型值会转为数字,可以指定小数位数" },
    { key:"number2", title:"计数器类型", type:"number", controls:true, precision:0, min:5, max:100, placeholder:"请输入数字" },
    { key:"percentage", title:"百分比类型", type:"percentage", precision:0, tips:"页面显示的是1,实际的值是0.01,请看右上角表单数据的值。" },
    { key:"discount", title:"折扣类型", type:"discount", tips:"页面显示的是1,实际的值是0.1,请看右上角表单数据的值。" },
    { key:"text2", title:"文本2", type:"text",prepend:"前置文字",append:"后置文字",prefixIcon:"el-icon-user" },
    // 选择型字段
    { key:"", title:"选择型字段", type:"bar-title" },
    {
      key:"radio1", title:"radio类型1", type:"radio",
      data:[
        { value:1, label:"选项一" },
        { value:2, label:"选项二" }
      ]
    },
    {
      key:"checkbox1", title:"checkbox类型1", type:"checkbox",
      data:[
        { value:1, label:"选项一" },
        { value:2, label:"选项二" }
      ]
    },
    {
      key:"select1", title:"select类型1", type:"select",
      data:[
        { value:1, label:"选项一" },
        { value:2, label:"选项二" }
      ]
    },
    { key:"address", title:"address类型", type:"address" },
    { key:"cascader2", title:"云端数据级联", type:"cascader",
      action:"admin/system/permission/sys/getAll",
      props:{
        list:"rows",
        value:"permission_id",
        label:"label",
        children:"children",
        multiple:true
      }
    },
    { key:"switch", title:"switch类型", type:"switch" },
    { key:"rate", title:"评分类型", type:"rate", allowHalf:false },
    { key:"slider", title:"滑块类型", type:"slider" },
    { key:"color1", title:"颜色类型1", type:"color" },
    { key:"color2", title:"颜色类型2", type:"color", showAlpha:true },
    // 文件上传
    { key:"", title:"文件上传", type:"bar-title" },
    { key:"image1", title:"image类型", type:"image", limit:6 },
    // 日期型字段
    { key:"", title:"日期型字段", type:"bar-title" },
    { key:"date", title:"date类型", type:"date", dateType:"date", tips:"可选择年月日" },
    { key:"dateTime", title:"dataTime类型", type:"date", dateType:"datetime", tips:"可选择年月日时分秒" },
    { key:"dateArr", title:"date类型范围", type:"date", dateType:"daterange" },
    { key:"dataTimeArr", title:"dataTime类型范围", type:"date", dateType:"datetimerange" },
    // 时间型字段
    { key:"", title:"时间型字段", type:"bar-title" },
    { key:"time1", title:"time类型1", type:"time" },
    { key:"timeArr1", title:"time类型范围1", type:"time", isRange:true },
    // 数据库联动字段
    { key:"", title:"数据库联动字段", type:"bar-title" },
    {
      key:"user_id", title:"用户选择器", type:"remote-select", placeholder:"请输入用户账号/昵称",
      action:"admin/select/kh/user",
    },
    {
      key: "user_id", title: "选择用户", type: "table-select", placeholder:"选择",
      action:"admin/system/user/sys/getList",
      columns:[
        { key:"nickname", title:"用户昵称", type:"text", nameKey:true },
        { key:"_id", title:"用户标识", type:"text", idKey:true },
        { key:"mobile", title:"手机号", type:"text" },
      ]
    },
    {
      key: "role1", title: "通过表格选择(单选)", type: "table-select", placeholder:"请选择角色",
      action:"admin/system/role/sys/getList",
      columns:[
        { key:"role_name", title:"角色昵称", type:"text", nameKey:true },
        { key:"role_id", title:"角色标识", type:"text", idKey:true }
      ],
    },
    {
      key: "role2", title: "通过表格选择(多选)", type: "table-select", placeholder:"请选择角色",
      action:"admin/system/role/sys/getList",
      columns:[
        { key:"role_name", title:"角色昵称", type:"text", nameKey:true },
        { key:"role_id", title:"角色标识", type:"text", idKey:true }
      ],
      multiple:true
    },
    // 布局
    { key:"", title:"横向布局", type:"bar-title" },
    { key:"", title:"", type:"group", justify:"start",
      columns:[
        { key:"text1", title:"单行文本1", type:"text" },
        { key:"text2", title:"单行文本2", type:"text" },
        { key:"text3", title:"单行文本3", type:"text" },
        { key:"text4", title:"单行文本4", type:"text" },
      ]
    },
    { key:"", title:"", type:"group", justify:"start",
      columns:[
        { key:"text5", title:"单行文本5", type:"text" },
        { key:"text6", title:"单行文本6", type:"text" },
        { key:"text7", title:"单行文本7", type:"text" },
        { key:"text8", title:"单行文本8", type:"text" },
      ]
    },
    { key:"", title:"", type:"group", justify:"end",
      columns:[
        { key:"text11", title:"单行文本11", type:"text", col:{ span: 6 } },
        { key:"text12", title:"单行文本12", type:"text", col:{ span: 6 } },
      ]
    },
    { key:"", title:"", type:"group", justify:"start",
      columns:[
        { key:"text13", title:"单行文本13", type:"text" },
        { key:"text14", title:"单行文本14", type:"text" },
      ]
    },
    { key:"", title:"", type:"group", justify:"start",
      columns:[
        { key:"text21", title:"单行文本21", type:"text", col:{ span:16 } },
        { key:"text22", title:"单行文本22", type:"text", col:{ span:24 } },
        { key:"text23", title:"单行文本23", type:"text", col:{ span:16 } },
        { key:"text24", title:"单行文本24", type:"text", col:{ span:24 } },
      ]
    },
    // 对象类型
    { key:"", title:"对象类型", type:"bar-title" },
    { key:"object1", title:"对象类型1", type:"object",
      columns:[
        { key:"a", title:"对象内属性a", type:"text" },
        { key:"b", title:"对象内属性b", type:"text" },
      ]
    },
    // 可以通过设置showLabel:false, 隐藏左侧的label
    { key:"object2", title:"对象类型2", type:"object", showLabel:false,
      columns:[
        { key:"a", title:"对象内属性a", type:"text" },
        { key:"b", title:"对象内属性b", type:"text" },
      ]
    },
    // 多层嵌套object
    { key:"object3", title:"对象类型3", type:"object", showLabel:true,
      columns:[
        { key:"a", title:"对象内属性a", type:"text" },
        { key:"b", title:"嵌套对象b", type:"object", showLabel:true, 
          columns:[
            { key:"b1", title:"嵌套对象b内属性b1", type:"text" },
            { key:"b2", title:"嵌套对象b内属性b2", type:"text" },
          ]
        },
      ]
    },
    // 特殊类型
    { key:"", title:"特殊类型", type:"bar-title" },
    { key:"editor", title:"富文本类型", type:"editor" },
    // 纯展示类型
    { key:"", title:"纯展示类型", type:"bar-title" },
    { key:"text100", title:"文本展示类型", type:"text-view" },
    { key:"text101", title:"金额展示类型", type:"money-view" },
    { key:"html102", title:"html展示类型", type:"html" },
    
  ]
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181

# before-action(请求前拦截)

<vk-data-form
  :before-action="form1.props.beforeAction"
></vk-data-form>
1
2
3
data: function() {
  // 组件创建时,进行数据初始化
  return {
    form1: {
      // 表单属性
      props: {
        
        beforeAction:(formData)=>{
          // 可在此处修改 formData 后返回 formData,若在此处return false,则表单不触发提交请求。
          return formData;
        },
        
      }
    }
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# rules(表单验证)

表单验证规则,和 element 表单验证规则一致,以下是部分示例

<vk-data-form
  :rules="form1.props.rules"
></vk-data-form>
1
2
3
data: function() {
  // 组件创建时,进行数据初始化
  return {
    form1: {
      data:{
        
      },
      // 表单属性
      props: {
        // 表单验证规则
        rules: {
          user_id: [
            // 必填
            { required: true, message: "用户ID不能为空", trigger: ['blur','change'] }
          ],
          money: [
            // 必填
            { required: true, message: "金额不能为空", trigger: ['blur','change'] },
            // 必须是数字
            { type: "number", message: "金额必须是数字", trigger: ['blur','change'] }
          ],
          mobile: [
            // 必填
            { required: true, message: '提现人手机号不能为空', trigger: ['blur','change'] },
            // 必须是手机号格式
            { validator: vk.pubfn.validator("mobile"),  message: '手机号格式错误', trigger: 'blur' }
          ],
          mobileCode: [
            // 必填
            { required: true, message: '验证码不能为空', trigger: ['blur','change'] },
            // 6位数数字验证码
            { validator: vk.pubfn.validator("mobileCode"),  message: '验证码格式错误', trigger: 'blur' }
          ],
          username:[
            // 必填
            { required: true, message: '用户名不能为空', trigger: ['blur','change'] },
            // 满足用户名格式
            { 
              validator:vk.pubfn.validator("username"), 
              message: '用户名以字母开头,长度在3~32之间,只能包含字母、数字和下划线', 
              trigger: 'blur'
            }
          ],
          password: [
            // 必填
            { required: true, message: '密码不能为空', trigger: ['blur','change'] },
            // 满足密码格式
            { 
              validator: vk.pubfn.validator("password"), 
              message: '密码长度在6~18之间,只能包含字母、数字和下划线', 
              trigger: 'blur' 
            }
          ],
          password2: [
            // 必填
            { required: true, message: '密码不能为空', trigger: ['blur','change'] },
            // 自定义
            { validator: (rule, value, callback)=>{
              if (value === '') {
                callback(new Error('请再次输入密码'));
              } else if (value !== that.form1.data.password) {
                callback(new Error('两次输入密码不一致!'));
              } else {
                callback();
              }
            }, trigger: ['blur','change'] }
          ],
          nickname: [
            // 必填
            { required: true, message: '昵称为必填字段', trigger: ['blur','change'] },
            // 长度在 2-20 个字
            { min: 2, max: 20, message: '昵称长度在 2 到 20 之间', trigger: 'blur' }
          ],
          card: [
            // 身份证
            { validator: vk.pubfn.validator("card"),  message: '身份证格式错误', trigger: 'blur' }
          ],
          payPwd: [
            // 支付密码
            { validator: vk.pubfn.validator("payPwd"),  message: '支付密码必须为 6位纯数字', trigger: 'blur' }
          ],
          postal: [
            // 邮政编码
            { validator: vk.pubfn.validator("postal"),  message: '邮政编码格式错误', trigger: 'blur' }
          ],
          email: [
            // 邮箱
            { validator: vk.pubfn.validator("email"),  message: '邮箱格式错误', trigger: 'blur' }
          ],
          QQ: [
            // qq
            { validator: vk.pubfn.validator("QQ"),  message: 'QQ号格式错误', trigger: 'blur' }
          ],
          URL: [
            // URL
            { validator: vk.pubfn.validator("URL"),  message: 'URL格式错误', trigger: 'blur' }
          ],
          IP: [
            // IP
            { validator: vk.pubfn.validator("IP"),  message: 'IP格式错误', trigger: 'blur' }
          ],
          date: [
            // 日期 2014-01-01(字符串)
            { validator: vk.pubfn.validator("date"),  message: 'date格式错误', trigger: 'blur' }
          ],
          time: [
            // 时间 12:00:00(字符串)
            { validator: vk.pubfn.validator("time"),  message: 'time格式错误', trigger: 'blur' }
          ],
          dateTime: [
            // 日期+时间 2014-01-01 12:00:00(字符串)
            { validator: vk.pubfn.validator("dateTime"),  message: 'dateTime格式错误', trigger: 'blur' }
          ],
          english: [
            // 英文
            { validator: vk.pubfn.validator("english"),  message: '只能输入英文', trigger: 'blur' }
          ],
          englishnumber: [
            // 只能是英文或数字
            { validator: vk.pubfn.validator("english+number"),  message: '只能输入英文或数字', trigger: 'blur' }
          ],
          englishnumber2: [
            // 只能是英文、数字、下划线
            { validator: vk.pubfn.validator("english+number+_"),  message: '只能输入英文、数字、下划线', trigger: 'blur' }
          ],
          chinese: [
            // 中文
            { validator: vk.pubfn.validator("chinese"),  message: '只能输入中文', trigger: 'blur' }
          ],
          lower: [
            // 小写字母
            { validator: vk.pubfn.validator("lower"),  message: '只能输入小写字母', trigger: 'blur' }
          ],
          upper: [
            // 大写字母
            { validator: vk.pubfn.validator("upper"),  message: '只能输入大写字母', trigger: 'blur' }
          ],
          HTML: [
            // HTML
            { validator: vk.pubfn.validator("HTML"),  message: 'html格式错误', trigger: 'blur' }
          ]
        }
      }
    }
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146

# 事件

事件名 说明 回调参数
success 表单提交成功 { data, formType }
fail 表单提交失败 { data, formType }
complete 表单提交结束 { data, formType }
cancel 表单点击取消按钮 -

如监听表单提交成功事件

<vk-data-form
  ...其他属性
  @success="onFormSuccess"
></vk-data-form>
1
2
3
4
methods: {
  onFormSuccess(res){
    console.log("表单提交成功", res);
  }
},
1
2
3
4
5

# 方法

通过 this.$refs.form1.xxx(); 方式调用

方法名 说明
submitForm 提交表单(提交前会自动进行一次表单验证)
resetForm 重置表单
clearValidate 移除整个表单的校验
validate 进行表单验证
validateField 对部分表单字段进行校验
setResetFormData 设置重置表单函数执行后,数据重置的数据源

# validate

that.$refs.form1.validate((valid) => {
  if (valid){
    // 验证通过
    
  }
});
1
2
3
4
5
6

# validateField

that.$refs.form1.validate("username",(errMsg, arr) => {
  if (errMsg) {
    // 未验证通过
    
  }
});
1
2
3
4
5
6

# setResetFormData

// 执行了这个setResetFormData方法后
this.$refs.form1.setResetFormData(data);
// 后面再执行 resetForm时,表单数据会变成 data 的值
this.$refs.form1.resetForm();
1
2
3
4

# 插槽

# columns中每一个key都是插槽名称

详情见示例:/pages_template/components/form/form-slot

# 重写rate字段的渲染示例

<vk-data-form
  ref="form1"
  v-model="form1.data"
  :rules="form1.props.rules"
  :action="form1.props.action"
  :form-type="form1.props.formType"
  :columns='form1.props.columns'
  :loading.sync="form1.props.loading"
  label-width="140px"
  @success="onFormSuccess"
>
  <!-- v-slot:rate 中的 rate 对应 columns中的 key, form对应 form1.data keyName 对应 columns中的 key -->
  <template v-slot:rate="{ form, keyName }">
    <view style="height: 36px;display: flex;align-items: center;">
      <el-rate v-model="form[keyName]"></el-rate>
    </view>
  </template>
</vk-data-form>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# 重写提交按钮的示例

<vk-data-form
  ref="form1"
  v-model="form1.data"
  :rules="form1.props.rules"
  :action="form1.props.action"
  :form-type="form1.props.formType"
  :columns='form1.props.columns'
  :loading.sync="form1.props.loading"
  label-width="140px"
  @success="onFormSuccess"
>
  <template v-slot:footer="{ loading }">
    <view style="text-align: center;" >
      <el-button :loading="loading" type="danger"  size="small" style="padding: 10px 40px;margin-right: 30px; " @click="adopt(-1)"> 拒绝 </el-button>
      <el-button :loading="loading" type="success" size="small" style="padding: 10px 40px; " @click="adopt(1)"> 通过 </el-button>
    </view>
  </template>
</vk-data-form>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 审核通过执行的方法
adopt(status){
  that.$refs.form1.submitForm({
    // data为额外提交的参数,真正提交的参数为form1.data+这里的data
    data:{
      status:status
    },
    success: (data) => {
      // 提交成功
      
    },
    fail: (data) => {
      // 提交失败
      
    }
  });
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# http请求模式

示例代码

<vk-data-form
  ref="form1"
  v-model="form1.data"
  :rules="form1.props.rules"
  action="https://www.xxx.com/xxx/xxx"
  :is-request="true"
  :request-header="{ 'content-type':'application/json; charset=utf-8'} "
  :columns="form1.props.columns"
></vk-data-form>
1
2
3
4
5
6
7
8
9

# 自定义function请求模式

vk-unicloud-admin-ui 的npm依赖版本需 >= 1.17.0

此方式同样支持http,且更自由化,比如可以在发起请求前处理请求参数,在请求成功后,处理返回参数等等。

优势:更自由化、基本可以满足所有需求场景

劣势:代码量较多

# 自定义function-http请求模式示例

<vk-data-form
  ref="form1"
  :action="form1.props.action"
  ...其他属性
></vk-data-form>
1
2
3
4
5
export default {
  data() {
    return {
      form1:{
        // 表单属性
        props: {
          
          
          action: (obj={})=>{
            let {
              data, // 请求数据
              success, // 成功回调
              fail, // 失败回调
              complete, // 成功回调
            } = obj;
            vk.request({
              url: `https://www.xxx.com/api/form`,
              method: "POST",
              header: {
                "content-type": "application/json; charset=utf-8",
              },
              data: data,
              success: (res) => {
                if (typeof success === "function") success(res);
              },
              fail: (res) => {
                if (typeof fail === "function") fail(res);
              },
              complete: (res) => {
                if (typeof complete === "function") complete(res);
              }
            });
          },
              
          
        }
      }
    }
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40

# 自定义function-云函数请求示例

<vk-data-form
  ref="form1"
  :action="form1.props.action"
  ...其他属性
></vk-data-form>
1
2
3
4
5
export default {
  data() {
    return {
      form1:{
        // 表单属性
        props: {
          
          
          action: (obj={})=>{
            let {
              data, // 请求数据
              success, // 成功回调
              fail, // 失败回调
              complete, // 成功回调
            } = obj;
            vk.callFunction({
              url: `云函数或云对象路径`,
              data: data,
              success: (res) => {
                if (typeof success === "function") success(res);
              },
              fail: (res) => {
                if (typeof fail === "function") fail(res);
              },
              complete: (res) => {
                if (typeof complete === "function") complete(res);
              }
            });
          },
              
          
        }
      }
    }
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

# 弹窗表单独立组件形式

# 接口名:vk.pubfn.openForm

介绍

如果把所有表单全写在一个vue页面内,会导致后期不方便维护,因此可以写成一个弹窗表单对应一个组件的形式。

打开弹窗API

vk.pubfn.openForm(name, value, this);

vk.pubfn.openForm('bindRole',{ item:  }); // 来源页面 /pages_plugs/system/user/list
1
2
3

参数

参数 说明 类型 默认值 可选值
name 弹窗表单组件名 String
value 传给表单的数据(格式为 { item: 当前行数据 } Object
this 页面或组件实例,在组件内调用时必传 Object 当前页面实例(this)

使用示例

/pages_plugs/system/user/list 用户管理页面为例,功能是点击弹出表单【绑定角色】

  • 1、新建一个表单组件,一般在该页面新建form目录,在form目录下创建弹窗表单组件,如 bindRole

bindRole.vue代码如下

<template>
	<vk-data-dialog
		v-model="value.show"
		:title="page.title"
		:top="page.top"
		:width="page.width"
		mode="form"
		@open="onOpen"
		@closed="onClose"
	>
		<!-- 页面主体内容开始 -->
		<vk-data-form
			ref="form1"
			:form-type="value.mode"
			v-loading="page.loading"
			v-model="form1.data"
			:rules="form1.props.rules"
			:action="form1.props.action"
			:columns="form1.props.columns"
			:loading.sync="form1.props.loading"
			:labelWidth="form1.props.labelWidth"
			:show-cancel="page.showCancel"
			:cancel-text="page.cancelText"
			:submit-text="page.submitText"
			@success="onFormSuccess"
		>
			<template v-slot:user_id>
				<view style="display: flex;align-items: center;">
					<el-avatar v-if="data.avatar" :src="data.avatar" fit="cover"></el-avatar>
					<text style="margin-left: 10px;">{{ data.nickname }}(ID:{{ data._id }})</text>
				</view>
			</template>
		</vk-data-form>
		<!-- 页面主体内容结束 -->
	</vk-data-dialog>
</template>

<script>
var that; // 当前页面对象
var vk = uni.vk; // vk实例
export default {
	props: {
		value: {
			Type: Object,
			default: function() {
				return {
					show: false,
					mode: "",
					item: ""
				};
			}
		}
	},
	data: function() {
		// 组件创建时,进行数据初始化
		return {
			// 页面基础数据
			page: {
				title: "角色绑定",
				submitText: "绑定",
				cancelText: "关闭",
				showCancel: true,
				top: "7vh",
				width:"820px",
				loading: false
			},
			data:{

			},
			form1: {
				// 表单请求数据,此处可以设置默认值
				data: {
					user_id: "",
					roleList: [],
					reset: true
				},
				// 表单属性
				props: {
					// 表单请求地址
					action: "admin/system/user/sys/bindRole",
					// 表单字段显示规则
					columns: [
						{ key:"user_id", title:"用户", type:"text" },
						{
							key: "roleList", title: "角色列表", type: "table-select", placeholder:"选择角色",
							action:"admin/system/role/sys/getList",
							columns:[
								{ key:"role_name", title:"角色昵称", type:"text", nameKey:true },
								{ key:"role_id", title:"角色标识", type:"text", idKey:true },
								{ key:"comment", title:"备注", type:"text" },
							],
							formData:{
								enable:true
							},
							queryColumns:[
								{ key: "role_name", title: "角色昵称", type: "text", width: 150, mode: "%%" },
								{ key: "role_id", title: "角色标识", type: "text", width: 150, mode: "%%" },
								{ key: "enable", type: "text", mode: "=", hidden:true }
							],
							multiple:true,
							pageSize:10, // 只有5和10可以选
						},
					],
					// 表单验证规则
					rules: {
						user_id: [
							{ "required": true, "message": "user_id不能为空", "trigger": "change" }
						]
					},
					// label宽度
					labelWidth:"100px",
					// label对其方式
					labelPosition:"left",
				}
			}
		};
	},
	mounted() {
		that = this;
		that.init();
	},
	methods: {
		// 初始化
		init() {
			let { value } = that;
			that.$emit("input", value);
		},
		// 监听 - 页面打开
		onOpen() {
			that = this;
			let { value } = that;
			let { role = [], _id } = value.item;
			that.data = value.item;
			that.form1.props.show = true;
			that.form1.data.user_id = _id;
			that.form1.data.roleList = role;
		},
		// 监听 - 页面关闭
		onClose() {
			that.$refs.form1.resetForm(); // 关闭时,重置表单
		},
		// 表单提交成功后
		onFormSuccess() {
			that.$set(that.value.item, "role", that.form1.data.roleList);
			that.value.show = false; // 关闭页面
			that.$emit("success");
		}
	},
	// 监听属性
	watch: {

	},
	// 计算属性
	computed: {}
};
</script>

<style lang="scss" scoped>

</style>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
  • 2、list.vue的 template 新增以下代码
<el-button type="primary" size="small" icon="el-icon-s-tools" @click="bindRoleBtn">角色绑定</el-button>

<bindRole v-model="formDatas.bindRole"></bindRole>

1
2
3
4
  • 3、list.vue的 script 新增以下代码
import bindRole from './form/bindRole'

export default {
  components:{
    bindRole,
  },
  data(){
    return {
      formDatas:{}, // 在此处定义下formDatas(无论该页面有几个弹窗表单,只需要定义这一个空对象即可)
    }
  },
  methods:{
    // 角色绑定按钮
    bindRoleBtn(){
    	let item = this.getCurrentRow(true);
    	vk.pubfn.openForm('bindRole',{ item });
    },
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
  • 4、完成,此时点击【角色绑定】按钮即可弹出表单【角色绑定】

# 表单可视化拖拽工具

可直接生成 vk框架代码element 原生代码 点击体验 (opens new window)

更多请见:/pages_template/components/form/form-pro