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,7 +58,7 @@ export default {
58 rangeIndex = index 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 // 初次加载时根据url hash跳转到指定锚点 63 // 初次加载时根据url hash跳转到指定锚点
64 if (this.$route.hash) { 64 if (this.$route.hash) {
examples/views/page/form/form-render.vue 0 → 100644
@@ -0,0 +1,56 @@ @@ -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 \ No newline at end of file 57 \ No newline at end of file
examples/views/page/form/index.vue 0 → 100644
@@ -0,0 +1,102 @@ @@ -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 \ No newline at end of file 103 \ No newline at end of file
examples/views/page/other.vue
1 <template> 1 <template>
2 <div> 2 <div>
3 <p>这是一个非markdown页面</p> 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 </div> 7 </div>
26 </template> 8 </template>
27 9
28 <script> 10 <script>
  11 +import EgForm from './form';
  12 +
29 export default { 13 export default {
30 name: 'other', 14 name: 'other',
  15 + components: { EgForm },
31 data() { 16 data() {
32 return { 17 return {
  18 + model: {},
33 option: { 19 option: {
34 - groups: ['basic', 'location'],  
35 list: [ 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 list: [ 23 list: [
43 { type: 'el-input', label: '名称', key: 'name' }, 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 list: [ 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 methods: { 89 methods: {
  90 + onValidate(v) {
  91 + console.log(v);
  92 + },
  93 + handleGetValue() {
  94 + this.$refs.form.validate();
  95 + }
65 } 96 }
66 } 97 }
67 </script> 98 </script>
68 \ No newline at end of file 99 \ No newline at end of file