Commit c68d92502303197f3dfed9bd157f9a66f61b88a8

Authored by Aaron
1 parent b14860fe
Exists in master and in 1 other branch legacy

新增预览版表单组件

examples/views/layout/component.vue
... ... @@ -58,7 +58,7 @@ export default {
58 58 rangeIndex = index
59 59 }
60 60 }
61   - this.currentAnchor = this.anchorList[rangeIndex].hash;
  61 + this.currentAnchor = this.anchorList[rangeIndex] ? this.anchorList[rangeIndex].hash : {};
62 62 };
63 63 // 初次加载时根据url hash跳转到指定锚点
64 64 if (this.$route.hash) {
... ...
examples/views/page/form/form-render.vue 0 → 100644
... ... @@ -0,0 +1,56 @@
  1 +<template>
  2 + <el-row :gutter="15" type="flex" style="flex-wrap: wrap;">
  3 + <template v-for="(item, index) in list">
  4 + <el-col v-if="item.group && item.list" :key="index" :span="item.group.span || 24">
  5 + <el-row :gutter="15" type="flex" style="flex-wrap: wrap;">
  6 + <el-col v-if="item.group.title" :span="24">{{ item.group.title || item.group }}</el-col>
  7 + <form-render :list="item.list" :model="itemKey ? model[itemKey] || {} : model" @item-change="onItemChange" @form-item-change="onFormItemChange" :itemKey="item.group.key"></form-render>
  8 + </el-row>
  9 + </el-col>
  10 + <el-col v-else :span="item.span || 12" :key="index">
  11 + <el-form-item :label="item.label" :label-width="item.labelWidth || '120px'" :prop="item.fullKey" :rules="item.rules">
  12 + <component :is="item.type" :value="itemValue({ item })" @input="v => handleInput({ value: v, item })"></component>
  13 + </el-form-item>
  14 + </el-col>
  15 + </template>
  16 + </el-row>
  17 +</template>
  18 +
  19 +<script>
  20 +export default {
  21 + name: 'form-render',
  22 + props: {
  23 + list: Array,
  24 + model: Object,
  25 + itemKey: String,
  26 + },
  27 + methods: {
  28 + itemValue({ item }) {
  29 + if (this.itemKey) {
  30 + const groupItem = this.model[this.itemKey] || {};
  31 + return groupItem[item.key];
  32 + } else {
  33 + return this.model[item.key];
  34 + }
  35 + },
  36 + handleInput({ value, item }) {
  37 + if (this.itemKey) {
  38 + this.$emit('item-change', { [this.itemKey]: { ...this.model[this.itemKey], [item.key]: value } });
  39 + } else {
  40 + this.$emit('item-change', { [item.key]: value });
  41 + }
  42 + this.$emit('form-item-change', { [item.fullKey]: value });
  43 + },
  44 + onItemChange(value) {
  45 + if (this.itemKey) {
  46 + this.$emit('item-change', { [this.itemKey]: { ...this.model[this.itemKey], ...value } });
  47 + } else {
  48 + this.$emit('item-change', value);
  49 + }
  50 + },
  51 + onFormItemChange(value) {
  52 + this.$emit('form-item-change', value);
  53 + }
  54 + }
  55 +}
  56 +</script>
0 57 \ No newline at end of file
... ...
examples/views/page/form/index.vue 0 → 100644
... ... @@ -0,0 +1,102 @@
  1 +<template>
  2 + <el-form ref="form" size="small" :model="formModel">
  3 + {{ formModel }}
  4 + <form-render :list="formList" :model="model" @item-change="onItemChange" @form-item-change="onFormItemChange"></form-render>
  5 + </el-form>
  6 +</template>
  7 +
  8 +<script>
  9 +import FormRender from './form-render';
  10 +
  11 +export default {
  12 + components: { FormRender },
  13 + props: {
  14 + value: Object,
  15 + list: Array,
  16 + },
  17 + data() {
  18 + return {
  19 + model: {},
  20 + formModel: {}
  21 + }
  22 + },
  23 + watch: {
  24 + value(val) {
  25 + const data = val || {};
  26 + this.model = data;
  27 + let formModel = {};
  28 + const setFormModelValue = (list, parentKey) => {
  29 + list.forEach(item => {
  30 + item.fullKey = `${parentKey ? `${parentKey}-${item.key}` : item.key}`;
  31 + if (item.value instanceof Object) {
  32 + setFormModelValue(Object.keys(item.value).map(key => ({ key, value: item.value[key] })), item.fullKey);
  33 + } else {
  34 + if (item.fullKey) {
  35 + formModel[item.fullKey] = item.value;
  36 + }
  37 + }
  38 + });
  39 + };
  40 + setFormModelValue(Object.keys(data).map(key => ({ key, value: data[key] })));
  41 + // console.log(formModel);
  42 + // Object.keys(formModel).forEach(key => {
  43 + // this.formModel[key] = formModel[key];
  44 + // });
  45 + if (Object.keys(formModel).length > 0) {
  46 + console.log(formModel);
  47 + this.formModel = formModel;
  48 + }
  49 + },
  50 + },
  51 + computed: {
  52 + formList() {
  53 + const newList = [...new Set(this.list)]
  54 + const generateFullKey = (list, parentKey) => {
  55 + list.forEach(item => {
  56 + if (item.group && item.list) {
  57 + if (item.group.key) {
  58 + item.fullKey = `${parentKey ? `${parentKey}-${item.group.key}` : item.group.key}`;
  59 + // if (item.fullKey) {
  60 + // this.formModel[item.fullKey] = '';
  61 + // }
  62 + } else {
  63 + item.fullKey = item.key;
  64 + // if (item.fullKey) {
  65 + // this.formModel[item.fullKey] = '';
  66 + // }
  67 + }
  68 + generateFullKey(item.list, item.fullKey);
  69 + } else {
  70 + item.fullKey = `${parentKey ? `${parentKey}-${item.key}` : item.key}`;
  71 + // if (item.fullKey) {
  72 + // this.formModel[item.fullKey] = '';
  73 + // }
  74 + }
  75 + });
  76 + };
  77 + generateFullKey(newList);
  78 + return newList;
  79 + }
  80 + },
  81 + methods: {
  82 + // 表单项值变化
  83 + onItemChange(item) {
  84 + this.$emit('input', { ...this.model, ...item });
  85 + },
  86 + // 表单相校验值变化
  87 + onFormItemChange(item) {
  88 + this.formModel = { ...this.formModel, ...item };
  89 + },
  90 + // 校验表单
  91 + validate() {
  92 + this.$refs.form.validate(valid => {
  93 + this.$emit("validate", valid);
  94 + });
  95 + },
  96 + }
  97 +}
  98 +</script>
  99 +
  100 +<style>
  101 +
  102 +</style>
0 103 \ No newline at end of file
... ...
examples/views/page/other.vue
1 1 <template>
2 2 <div>
3 3 <p>这是一个非markdown页面</p>
4   - <el-form size="small">
5   - <el-row :gutter="15" type="flex" style="flex-wrap: wrap;">
6   - <template v-for="(item, index) in option.list2">
7   - <el-col v-if="item.group && item.list" :key="index" :span="item.group.span || 24">
8   - <el-row :gutter="15" type="flex" style="flex-wrap: wrap;">
9   - <el-col :span="24">{{ item.group.title || item.group }}</el-col>
10   - <el-col v-for="(comp, idx) in item.list" :key="idx" :span="comp.span || 12">
11   - <el-form-item :label="comp.label" :label-width="comp.labelWidth || '120px'" :prop="comp.key" :rules="comp.rules">
12   - <component :is="comp.type"></component>
13   - </el-form-item>
14   - </el-col>
15   - </el-row>
16   - </el-col>
17   - <el-col v-else :span="item.span || 12" :key="index">
18   - <el-form-item :label="item.label" :label-width="item.labelWidth || '120px'" :prop="item.key" :rules="item.rules">
19   - <component :is="item.type"></component>
20   - </el-form-item>
21   - </el-col>
22   - </template>
23   - </el-row>
24   - </el-form>
  4 + <pre>{{ model }}</pre>
  5 + <el-button size="mini" @click="handleGetValue">校验</el-button>
  6 + <eg-form ref="form" v-model="model" :list="option.list" @validate="onValidate"></eg-form>
25 7 </div>
26 8 </template>
27 9  
28 10 <script>
  11 +import EgForm from './form';
  12 +
29 13 export default {
30 14 name: 'other',
  15 + components: { EgForm },
31 16 data() {
32 17 return {
  18 + model: {},
33 19 option: {
34   - groups: ['basic', 'location'],
35 20 list: [
36   - { type: 'el-input', label: '名称', key: 'name' },
37   - { type: 'el-input', label: '地址', key: 'location' },
38   - ],
39   - list2: [
40 21 {
41   - group: { title: 'basic', span: 12 },
  22 + group: { title: '基础信息', span: 12 },
42 23 list: [
43 24 { type: 'el-input', label: '名称', key: 'name' },
44   - { type: 'el-input-number', label: '名称1', key: 'name1' },
45   - { type: 'el-switch', label: '名称2', key: 'name2' },
46   - { type: 'el-input', label: '名称3', key: 'name3' },
  25 + { type: 'el-input-number', label: '年龄', key: 'age' },
47 26 ],
48 27 },
49 28 {
50   - group: 'location',
  29 + group: { title: '住址', span: 24, key: 'location' },
51 30 list: [
52   - { type: 'el-input', label: '地址', key: 'location' },
  31 + { type: 'el-input', label: '地址简称', key: 'locationMin' },
  32 + {
  33 + group: { span: 12, key: 'district' },
  34 + list: [
  35 + { type: 'el-input', label: '省', key: 'province', span: 24, rules: [{ required: true, message: '请输入省' }] },
  36 + { type: 'el-input', label: '市', key: 'city', span: 24 },
  37 + ],
  38 + },
  39 + {
  40 + group: { title: '小区信息', span: 24 },
  41 + list: [
  42 + { type: 'el-input', label: '小区名', key: 'areaName', span: 24 },
  43 + { type: 'el-input', label: '门牌号', key: 'homeNum', span: 24 },
  44 + {
  45 + group: { title: 'A栋', span: 24 },
  46 + list: [
  47 + { type: 'el-input', label: '人数', key: 'anumber', span: 24 },
  48 + ],
  49 + },
  50 + {
  51 + group: { title: 'B栋', span: 24, key: 'bside' },
  52 + list: [
  53 + { type: 'el-input', label: '人数', key: 'bnumber', span: 24 },
  54 + ],
  55 + }
  56 + ],
  57 + }
53 58 ],
54 59 },
55   - { type: 'el-input', label: '名称', key: 'name' },
56   - { type: 'el-input', label: '地址', key: 'location' },
57   - { type: 'el-input-number', label: '名称1', key: 'name1' },
58   - { type: 'el-switch', label: '名称2', key: 'name2' },
59   - { type: 'el-input', label: '名称3', key: 'name3' },
  60 + { type: 'el-input', label: '身高', key: 'height' },
  61 + { type: 'el-input', label: '体重', key: 'weight' },
60 62 ]
61 63 }
62 64 }
63 65 },
  66 + mounted() {
  67 + setTimeout(() => {
  68 + this.model = {
  69 + age: 7,
  70 + name: '1',
  71 + location: {
  72 + locationMin: 'a',
  73 + district: {
  74 + province: 'p',
  75 + city: 'c'
  76 + },
  77 + areaName: 'a',
  78 + homeNum: 'n',
  79 + anumber: '1',
  80 + bside: {
  81 + bnumber: '2'
  82 + }
  83 + },
  84 + height: '3',
  85 + weight: '4'
  86 + }
  87 + }, 3000);
  88 + },
64 89 methods: {
  90 + onValidate(v) {
  91 + console.log(v);
  92 + },
  93 + handleGetValue() {
  94 + this.$refs.form.validate();
  95 + }
65 96 }
66 97 }
67 98 </script>
68 99 \ No newline at end of file
... ...