# 表单布局组件

# 基本使用

<template>
  <el-card>
    <form-grid :model="form" :fields="fields"></form-grid>
  </el-card>
</template>

<script>
  export default {
    data() {
      return {
        form: { name: "", sex: "" },
        fields: [
          {
            label: "姓名",
            name: "name",
            component: "Input",
          },
          {
            label: "性别",
            name: "sex",
            component: "Select",
            dict: [
              {
                name: "女",
                value: 0,
              },
              {
                name: "男",
                value: 1,
              },
            ],
          },
          {
            label: "开始时间",
            name: "start",
            component: "DatePicker",
          },
          {
            label: "结束时间",
            name: "end",
            component: "DatePicker",
          },
        ],
      };
    },
  };
</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
显示代码 复制代码

# 全部禁用

<template>
  <el-card>
    <form-grid :model="form" :fields="fields" :disabled="true"></form-grid>
  </el-card>
</template>

<script>
  export default {
    data() {
      return {
        form: { name: "张三", sex: 0, start: new Date(), end: new Date("2000-2-12"), progress: 30 },
        fields: [
          {
            label: "姓名",
            name: "name",
            component: "Input",
            // colCount: 1,
            props: { placeholder: "奥术大师多" },
          },
          {
            label: "开始时间",
            name: "start",
            component: "DatePicker",
            format: "date",
            props: {
              disabledDate: "now>time",
            },
          },
          {
            label: "结束时间",
            name: "end",
            format: "date",
            component: "DatePicker",
            props: {
              disabledDate: "time>now",
            },
          },
          {
            label: "姓别",
            name: "sex",
            component: "Select",
            props: {},
            tag: true,
            dict: [
              {
                name: "女",
                value: 0,
              },
              {
                name: "男",
                value: 1,
              },
            ],
          },
          {
            label: "进度",
            name: "progress",
            component: "Input",
            // colCount: 2,
            props: {},
            progress: true,
          },
        ],
      };
    },
  };
</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
显示代码 复制代码

# 预览状态

张三
2020-12-17
2000-02-12
30%

FormGrid Field format、tag、progress 只有在预览的情况下生效

<template>
  <el-card>
    <form-grid :model="form" :fields="fields" :preview="true"></form-grid>
  </el-card>
</template>

<script>
  export default {
    data() {
      return {
        form: { name: "张三", sex: 0, start: new Date(), end: new Date("2000-2-12"), progress: 30 },
        fields: [
          {
            label: "姓名",
            name: "name",
            component: "Input",
            // colCount: 1,
            props: { placeholder: "奥术大师多" },
          },
          {
            label: "开始时间",
            name: "start",
            component: "DatePicker",
            format: "date",
            props: {
              disabledDate: "now>time",
            },
          },
          {
            label: "结束时间",
            name: "end",
            format: "date",
            component: "DatePicker",
            props: {
              disabledDate: "time>now",
            },
          },
          {
            label: "姓别",
            name: "sex",
            component: "Select",
            props: {},
            tag: true,
            dict: [
              {
                name: "女",
                value: 0,
              },
              {
                name: "男",
                value: 1,
              },
            ],
          },
          {
            label: "进度",
            name: "progress",
            component: "Input",
            // colCount: 2,
            props: {},
            progress: true,
          },
        ],
      };
    },
  };
</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
显示代码 复制代码

# 设置默认值

{"name":"张三","sex":0,"start":"2020-12-17T05:59:07.061Z","end":"2020-12-17T05:59:07.061Z"}
<template>
  <el-card>
    <form-grid :model="form" :fields="fields"> </form-grid>
    {{JSON.stringify(form)}}
  </el-card>
</template>

<script>
  export default {
    data() {
      return {
        form: { name: "张三", sex: 0, start: new Date(), end: new Date() },
        fields: [
          {
            label: "姓名",
            name: "name",
            component: "Input",
          },
          {
            label: "性别",
            name: "sex",
            component: "Select",
            dict: [
              {
                name: "女",
                value: 0,
              },
              {
                name: "男",
                value: 1,
              },
            ],
          },
          {
            label: "开始时间",
            name: "start",
            component: "DatePicker",
          },
          {
            label: "结束时间",
            name: "end",
            component: "DatePicker",
          },
        ],
      };
    },
  };
</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
显示代码 复制代码

# 设置组件属性

0/30
<template>
  <el-card>
    <form-grid :model="form" :fields="fields"> </form-grid>
  </el-card>
</template>

<script>
  export default {
    data() {
      return {
        form: { name: "", sex: "", start: "", end: "" },
        fields: [
          {
            label: "姓名",
            name: "name",
            component: "Input",
          },
          {
            label: "性别",
            name: "sex",
            component: "Select",
            dict: [
              {
                name: "女",
                value: 0,
              },
              {
                name: "男",
                value: 1,
              },
            ],
          },
          {
            label: "开始时间",
            name: "start",
            component: "DatePicker",
          },
          {
            label: "结束时间",
            name: "end",
            component: "DatePicker",
          },
          {
            label: "描述",
            name: "desc",
            component: "Input",
            colCount: 2,
            props: {
              type: "textarea",
              maxlength: 30,
              showWordLimit: true,
            },
          },
        ],
      };
    },
  };
</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
显示代码 复制代码

# 表单验证

<template>
  <el-card>
    <form-grid :model="form" :fields="fields" :rules="rules" ref="form">
      <el-row type="flex" justify="end">
        <el-col :span="6">
          <el-button size="small" @click="reset">重置</el-button>
          <el-button size="small" type="primary" @click="submit">提交</el-button>
        </el-col>
      </el-row>
    </form-grid>
  </el-card>
</template>

<script>
  export default {
    data() {
      var checkAge = (rule, value, callback) => {
        if (!value) {
          return callback(new Error("年龄不能为空"));
        }
        setTimeout(() => {
          if (value < 18) {
            callback(new Error("必须年满18岁"));
          } else {
            callback();
          }
        }, 1000);
      };
      var validatePass = (rule, value, callback) => {
        if (value === "") {
          callback(new Error("请输入密码"));
        } else {
          if (this.form.checkPass !== "") {
            this.$refs.form.validateField("checkPass");
          }
          callback();
        }
      };
      var validatePass2 = (rule, value, callback) => {
        if (value === "") {
          callback(new Error("请再次输入密码"));
        } else if (value !== this.form.pass) {
          callback(new Error("两次输入密码不一致!"));
        } else {
          callback();
        }
      };
      return {
        form: { pass: "", checkPass: "", age: "" },
        rules: {
          pass: [
            { required: true, message: "请输入密码", trigger: "blur" },
            { validator: validatePass, trigger: "blur" },
          ],
          checkPass: [
            { required: true, message: "请输入确认密码", trigger: "blur" },
            { validator: validatePass2, trigger: "blur" },
          ],
          age: [
            { required: true, message: "请输入年龄", trigger: "blur" },
            { validator: checkAge, trigger: "blur" },
          ],
        },
        fields: [
          {
            label: "密码",
            name: "pass",
            props: {
              type: "password",
            },
            component: "Input",
          },
          {
            label: "确认密码",
            name: "checkPass",
            props: {
              type: "password",
            },
            component: "Input",
          },
          {
            label: "年龄",
            name: "age",
            component: "Input",
          },
        ],
      };
    },
    methods: {
      submit() {
        this.$refs.form.validate((valid) => {
          if (valid) {
            alert("submit!");
          } else {
            console.log("error submit!!");
            return false;
          }
        });
      },
      reset() {
        this.$refs.form.resetFields();
      },
    },
  };
</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
显示代码 复制代码

# 使用插槽

-
0/30

组件插槽使用${name}Component
form 元素布局插槽使用${name}

<template>
  <el-card>
    <form-grid :model="form" :fields="fields">
      <template #startComponent>
        <el-date-picker
          v-model="form.start"
          align="right"
          type="date"
          placeholder="选择日期"
          :picker-options="pickerOptions"
        >
        </el-date-picker>
      </template>
      <template #activeDate>
        <col-layout :col-count="2">
          <el-form-item label="活动时间:">
            <el-col :span="11">
              <el-date-picker
                type="date"
                placeholder="选择日期"
                v-model="form.activeStart"
                style="width: 100%;"
              ></el-date-picker>
            </el-col>
            <el-col class="line" :span="2">-</el-col>
            <el-col :span="11">
              <el-time-picker
                placeholder="选择时间"
                v-model="form.activeEnd"
                style="width: 100%;"
              ></el-time-picker>
            </el-col>
          </el-form-item>
        </col-layout>
      </template>
    </form-grid>
  </el-card>
</template>

<script>
  export default {
    data() {
      return {
        form: { name: "", sex: "", start: "", end: "", activeStart: "", activeEnd: "" },
        pickerOptions: {
          disabledDate(time) {
            return time.getTime() > Date.now();
          },
          shortcuts: [
            {
              text: "今天",
              onClick(picker) {
                picker.$emit("pick", new Date());
              },
            },
            {
              text: "昨天",
              onClick(picker) {
                const date = new Date();
                date.setTime(date.getTime() - 3600 * 1000 * 24);
                picker.$emit("pick", date);
              },
            },
            {
              text: "一周前",
              onClick(picker) {
                const date = new Date();
                date.setTime(date.getTime() - 3600 * 1000 * 24 * 7);
                picker.$emit("pick", date);
              },
            },
          ],
        },
        fields: [
          {
            label: "姓名",
            name: "name",
            component: "Input",
          },
          {
            label: "性别",
            name: "sex",
            component: "Select",
            dict: [
              {
                name: "女",
                value: 0,
              },
              {
                name: "男",
                value: 1,
              },
            ],
          },
          {
            label: "开始时间",
            name: "start",
            component: "DatePicker",
          },
          {
            label: "活动时间",
            name: "activeDate",
            isNewLine: true,
            component: "DatePicker",
          },
          {
            label: "描述",
            name: "desc",
            component: "Input",
            colCount: 2,
            props: {
              type: "textarea",
              maxlength: 30,
              showWordLimit: true,
            },
          },
        ],
      };
    },
  };
</script>

<style>
  .line {
    text-align: center;
  }
</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
显示代码 复制代码

# API

# FormGrid

参数 说明 类型 可选值 默认值
model 表单数据对象 object
rules 表单验证规则 object
inline 行内表单模式 boolean false
label-position 表单域标签的位置,如果值为 left 或者 right 时,则需要设置 label-width string right/left/top right
label-width 表单域标签的宽度,例如 '50px'。作为 Form 直接子元素的 form-item 会继承该值。支持 auto。 string
label-suffix 表单域标签的后缀 string
hide-required-asterisk 是否显示必填字段的标签旁边的红色星号 boolean false
show-message 是否显示校验错误信息 boolean true
inline-message 是否以行内形式展示校验信息 boolean false
status-icon 是否在输入框中显示校验结果反馈图标 boolean false
validate-on-rule-change 是否在 rules 属性改变后立即触发一次验证 boolean true
size 用于控制该表单内组件的尺寸 string medium / small / mini
disabled 是否禁用该表单内的所有组件。若设置为 true,则表单内组件上的 disabled 属性不再生效 boolean false
col-count 一行显示多少个表单元素 number - 4
fields 布局表单元素配置 Field[] - []
preview 表单预览状态,不可编辑 boolean false

# FormGrid Field

参数 说明 类型 可选值 默认值
isNewLine 是否换行 boolean - false
colCount 占用一行显示个数 number - -
component 对应全局map配置 string 参考 map配置 -
dict 字典配置, component 为 Select 有作用 Array - -
props 参考对应 component 配置 object - -
label 标签文本 string
label-width 表单域标签的的宽度,例如 '50px'。支持 auto。 string
required 是否必填,如不设置,则会根据校验规则自动生成 boolean false
rules 表单验证规则 object
error 表单域验证错误信息, 设置该值会使表单验证状态变为 error,并显示该错误信息 string
show-message 是否显示校验错误信息 boolean true
inline-message 以行内形式展示校验信息 boolean false
size 用于控制该表单域下组件的尺寸 string medium / small / mini -
format 数据格式化 preview 下生效 string usetime|
currency|
progress|
date|
dateTime|
time
-
tag 是否使用 tag 组件; 如果是 object 参考tag (opens new window);如果是 function 则回调返回值就是 tag 属性。返回值参考tag (opens new window) preview 下生效 boolean|
object|
Function(callback:Funtion({ row, column, $index })
- -
progress 是否使用 progress 组件,如果是 function 则回调返回值就是 progress 属性。返回值参考progress (opens new window) preview 下生效 boolean|
Function(callback:Funtion({ row, column, $index })
- -

# FormGrid Methods

方法名 说明 参数
validate 对整个表单进行校验的方法,参数为一个回调函数。该回调函数会在校验结束后被调用,并传入两个参数:是否校验成功和未通过校验的字段。若不传入回调函数,则会返回一个 promise Function(callback: Function(boolean, object))
validateField 对部分表单字段进行校验的方法 Function(props: array | string, callback: Function(errorMessage: string))
resetFields 对整个表单进行重置,将所有字段值重置为初始值并移除校验结果
clearValidate 移除表单项的校验结果。传入待移除的表单项的 prop 属性或者 prop 组成的数组,如不传则移除整个表单的校验结果 Function(props: array | string)

# FormGrid Events

事件名称 说明 回调参数
validate 任一表单项被校验后触发 被校验的表单项 prop 值,校验是否通过,错误消息(如果存在)