Commit 096f9b03d322b3ef83bb140a7259d051ea693c5a

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

新增Detail组件,修复Scheme组件设置值BUG

examples/router/routes.js
... ... @@ -19,6 +19,12 @@ const _components = [
19 19 group: '高级',
20 20 children: [
21 21 {
  22 + path: 'detail',
  23 + name: 'detail',
  24 + meta: { title: 'Detail 详情' },
  25 + component: () => import('@/views/docs/detail.md'),
  26 + },
  27 + {
22 28 path: 'form',
23 29 name: 'form',
24 30 meta: { title: 'Form 表单' },
... ...
examples/views/docs/detail.md 0 → 100644
... ... @@ -0,0 +1,52 @@
  1 +# Detail 详情
  2 +
  3 +将Form组件的值展示位详情
  4 +
  5 +## 基础用法
  6 +
  7 +配置项list将无视配置的type,统一渲染为label
  8 +
  9 +:::snippet 使用`list`属性设置数据源,列表项中的`type`指定组件类型,每一项都已设置为**el-form-item**的子组件
  10 +
  11 +```html
  12 +<template>
  13 + <eagle-detail v-model="detailModel" :list="detailList" style="width: 800px;"></eagle-detail>
  14 +</template>
  15 +
  16 +<script>
  17 +export default {
  18 + data() {
  19 + return {
  20 + detailList: [
  21 + { type: 'el-input', key: 'name', label: '名称' },
  22 + { type: 'eagle-select', key: 'address', label: '住址', group: '地址信息' },
  23 + { type: 'el-input', key: 'postcode', label: '邮编', group: '地址信息' },
  24 + { type: 'el-input', key: 'number', label: '楼栋号', group: '地址信息' },
  25 + ],
  26 + detailModel: {
  27 + name: '老A',
  28 + address: 'Any where',
  29 + postcode: 123456,
  30 + number: 'N栋N-N'
  31 + }
  32 + }
  33 + },
  34 +}
  35 +</script>
  36 +```
  37 +
  38 +:::
  39 +
  40 +## Attribute 属性
  41 +
  42 +参数|说明|类型|可选值|默认值
  43 +-|-|-|-|-
  44 +value / v-model | 绑定值 | Object | - | -
  45 +list | 表单项配置列表 | Array | - | []
  46 +
  47 +## List 表单项配置列表
  48 +
  49 +参数|说明|类型|可选值|默认值
  50 +-|-|-|-|-
  51 +key | 参数名 | String | - | -
  52 +label | 参数标签 | String | - | -
0 53 \ No newline at end of file
... ...
examples/views/docs/scheme.md
... ... @@ -29,10 +29,13 @@ Scheme是一个数æ®é©±åŠ¨çš„è§£å†³æ–¹æ¡ˆï¼Œé€šè¿‡æ—¢å®šçš„ä¸šåŠ¡é…ç½®å‚æ•°ï¼
29 29 <template #form-item-status="{ model }">
30 30 <el-input-number v-model="model.status"></el-input-number>
31 31 </template>
32   - <template #dialog-view="{ row }">
  32 + <template #view-item-code="{ model }">
  33 + <el-input disabled :value="model.code"></el-input>
  34 + </template>
  35 + <!-- <template #dialog-view="{ row }">
33 36 <div>这是一个自定义弹出框内容</div>
34 37 <div>{{ row }}</div>
35   - </template>
  38 + </template> -->
36 39 <template #dialog-status>
37 40 <div>这是Status的内容</div>
38 41 </template>
... ...
packages/detail/index.vue 0 → 100644
... ... @@ -0,0 +1,164 @@
  1 +<style>
  2 +.eagle-detail {
  3 + padding: 0px;
  4 +}
  5 +.eagle-detail__group-title {
  6 + font-weight: bold;
  7 + padding: 15px 5px;
  8 + border-bottom: 1px solid #d9d9d9;
  9 + margin-bottom: 30px;
  10 +}
  11 +.eagle-detail__group-icon {
  12 + padding-right: 10px;
  13 +}
  14 +.eagle-detail__group-content {
  15 + margin: 15px 0px;
  16 +}
  17 +</style>
  18 +
  19 +<template>
  20 + <el-form class="eagle-detail" :model="model" v-bind="detailProps">
  21 + <el-row :gutter="15">
  22 + <template v-for="(data, index) in listOption.dataList">
  23 + <template v-if="listOption.isGroup">
  24 + <slot v-if="$scopedSlots[data.key] || $slots[data.key]" :name="data.key" v-bind="data"></slot>
  25 + <el-col v-else class="eagle-detail__group-title" :span="24" :key="data.key">
  26 + <i v-if="data.icon" :class="`el-icon-${data.icon} eagle-detail__group-icon`"></i>
  27 + <span>{{ data.label }}</span>
  28 + </el-col>
  29 + </template>
  30 + <el-row :class="{ 'eagle-detail__group-content': listOption.isGroup }" :key="'group-content-' + index" :gutter="15">
  31 + <template v-for="(item, index) in data.list">
  32 + <el-col :key="index + 'data'" :span="!item.span ? span : item.span">
  33 + <el-form-item :label="item.label" :label-width="item.label ? undefined : item.labelWidth || '0px'" :prop="item.key">
  34 + <slot v-if="$scopedSlots[`item-${item.key}`] || $slots[`item-${item.key}`]" :name="`item-${item.key}`" :model="model" v-bind="item"></slot>
  35 + <label v-else><b>{{ model[item.key] }}</b></label>
  36 + </el-form-item>
  37 + </el-col>
  38 + </template>
  39 + </el-row>
  40 + </template>
  41 + </el-row>
  42 + </el-form>
  43 +</template>
  44 +
  45 +<script>
  46 +export default {
  47 + name: 'Detail',
  48 + props: {
  49 + // 用于实例化本组件绑定v-model的值
  50 + value: {
  51 + type: Object,
  52 + default: () => {
  53 + return {};
  54 + }
  55 + },
  56 + // 配置列表
  57 + list: {
  58 + type: Array,
  59 + required: true
  60 + },
  61 + // 表单参数
  62 + detailProps: {
  63 + type: Object,
  64 + default() {
  65 + return {
  66 + size: 'small',
  67 + 'label-width': '70px'
  68 + }
  69 + }
  70 + },
  71 + // 表单项占位
  72 + span: {
  73 + type: Number,
  74 + default: 8
  75 + }
  76 + },
  77 + data() {
  78 + return {
  79 + // 编辑器表单模型
  80 + model: {}
  81 + };
  82 + },
  83 + created() {
  84 + // 初始化表单模型
  85 + this.initModel(this.list);
  86 + },
  87 + mounted() {
  88 + this.setModelValue(this.value);
  89 + },
  90 + computed: {
  91 + // 配置列表键值对形式
  92 + listKeySet() {
  93 + let result = {};
  94 + this.list.forEach(item => {
  95 + result[item.key] = item;
  96 + });
  97 + return result;
  98 + },
  99 + // 配置列表解析为渲染配置项
  100 + listOption() {
  101 + let groupSet = {};
  102 + this.list.forEach(data => {
  103 + if (data.group) {
  104 + if (typeof data.group === 'object') {
  105 + if (!groupSet[`group-${data.group.key}`]) {
  106 + groupSet[`group-${data.group.key}`] = {
  107 + icon: data.group.icon,
  108 + label: data.group.label,
  109 + list: []
  110 + };
  111 + }
  112 + groupSet[`group-${data.group.key}`].list.push(data);
  113 + } else if (typeof data.group === 'string') {
  114 + if (!groupSet[data.group]) {
  115 + groupSet[data.group] = {
  116 + label: data.group,
  117 + list: []
  118 + };
  119 + }
  120 + groupSet[data.group].list.push(data);
  121 + }
  122 + } else {
  123 + if (!groupSet['group-default']) {
  124 + groupSet['group-default'] = {
  125 + label: '基本信息',
  126 + list: []
  127 + };
  128 + }
  129 + groupSet['group-default'].list.push(data);
  130 + }
  131 + });
  132 + const isGroup = Object.keys(groupSet).length > 1;
  133 + const dataList = Object.keys(groupSet).map(key => {
  134 + return { key, ...groupSet[key] };
  135 + })
  136 + return { isGroup, dataList };
  137 + }
  138 + },
  139 + watch: {
  140 + // 组件外部v-model值更新后同步刷新model
  141 + value(val) {
  142 + this.setModelValue(val);
  143 + },
  144 + // 配置列表有改动时初始化表单模型
  145 + list(value) {
  146 + this.initModel(value);
  147 + },
  148 + },
  149 + methods: {
  150 + // 设置表单值
  151 + setModelValue(value) {
  152 + Object.keys(this.model).forEach(key => {
  153 + this.model[key] = value ? value[key] : undefined;
  154 + });
  155 + },
  156 + // 初始化表单模型
  157 + initModel(list) {
  158 + list.forEach(item => {
  159 + this.$set(this.model, item.key, item.default || undefined)
  160 + });
  161 + },
  162 + }
  163 +};
  164 +</script>
0 165 \ No newline at end of file
... ...
packages/form/index.vue
... ... @@ -101,24 +101,12 @@ export default {
101 101 model: {}
102 102 };
103 103 },
104   - watch: {
105   - // 组件外部v-model值更新后同步刷新model
106   - value(val) {
107   - Object.keys(this.model).forEach(key => {
108   - this.model[key] = val ? val[key] : undefined;
109   - });
110   - },
111   - // 配置列表有改动时初始化表单模型
112   - list(value) {
113   - this.initModel(value);
114   - },
115   - model: {
116   - handler(val) {
117   - this.$emit("input", val);
118   - this.$emit("change", val);
119   - },
120   - deep: true
121   - }
  104 + created() {
  105 + // 初始化表单模型
  106 + this.initModel(this.list);
  107 + },
  108 + mounted() {
  109 + this.setModelValue(this.value);
122 110 },
123 111 computed: {
124 112 // 配置列表键值对形式
... ... @@ -170,11 +158,33 @@ export default {
170 158 return { isGroup, dataList };
171 159 }
172 160 },
173   - created() {
174   - // 初始化表单模型
175   - this.initModel(this.list);
  161 + watch: {
  162 + // 组件外部v-model值更新后同步刷新model
  163 + value(val) {
  164 + this.setModelValue(val);
  165 + },
  166 + // 配置列表有改动时初始化表单模型
  167 + list(value) {
  168 + this.initModel(value);
  169 + },
  170 + model: {
  171 + handler(val) {
  172 + this.$emit("input", val);
  173 + this.$emit("change", val);
  174 + },
  175 + deep: true
  176 + }
176 177 },
177 178 methods: {
  179 + // 设置表单值
  180 + setModelValue(value) {
  181 + Object.keys(this.model).forEach(key => {
  182 + this.model[key] = value ? value[key] : undefined;
  183 + });
  184 + this.$nextTick(() => {
  185 + this.$refs.form.clearValidate();
  186 + });
  187 + },
178 188 // 绑定提示组件参数
179 189 bindItemTip(tip) {
180 190 if (typeof tip === 'string') {
... ...
packages/index.js
1 1 import Code from './code'
2 2 import Confirm from './confirm'
  3 +import Detail from './detail'
3 4 import DistPicker from './dist-picker'
4 5 import Editor from './editor'
5 6 import FileUpload from './file-upload'
... ... @@ -19,6 +20,7 @@ import TreeSelect from &#39;./tree-select&#39;
19 20 const components = {
20 21 Code,
21 22 Confirm,
  23 + Detail,
22 24 DistPicker,
23 25 Editor,
24 26 FileUpload,
... ...
packages/scheme/index.vue
... ... @@ -109,7 +109,7 @@
109 109 </div>
110 110 </div>
111 111 <el-dialog :custom-class="dialogProps['custom-class'] || 'eagle-scheme__dialog'" :title="dialogProps.title || dialogTitle" :visible.sync="dialogVisible" v-bind="{ width: '65%', ...dialogProps }">
112   - <eagle-form v-if="dialogType === 'dialog-form'" :list="_formList" v-model="formModel" :span="formProps.span || 12" :formProps="{ size: 'small', 'label-width': '90px', ...formProps }" @submit="handleSubmit" @cancel="handleCancel">
  112 + <eagle-form v-if="dialogType === 'dialog-form' && !$scopedSlots['dialog-form'] && !$slots['dialog-form']" :list="_formList" v-model="formModel" :span="formProps.span || 12" :formProps="{ size: 'small', 'label-width': '90px', ...formProps }" @submit="handleSubmit" @cancel="handleCancel">
113 113 <!-- 表单分组具名插槽 -->
114 114 <template v-for="key in formGroupSlotsKeys">
115 115 <slot v-if="$scopedSlots[`form-${key}`] || $slots[`form-${key}`]" :name="`form-${key}`" :slot="key" :model="formModel"></slot>
... ... @@ -119,9 +119,18 @@
119 119 <slot v-if="$scopedSlots[`form-item-${item.key}`] || $slots[`form-item-${item.key}`]" :name="`form-item-${item.key}`" :slot="`item-${item.key}`" :model="formModel"></slot>
120 120 </template>
121 121 </eagle-form>
122   - <template v-else>
123   - <slot :name="dialogType" :row="tableCurrentRow"></slot>
124   - </template>
  122 + <eagle-detail v-else-if="dialogType === 'dialog-view' && !$scopedSlots['dialog-view'] && !$slots['dialog-view']" v-model="formModel" :list="_formList">
  123 + <!-- 表单分组具名插槽 -->
  124 + <template v-for="key in formGroupSlotsKeys">
  125 + <slot v-if="$scopedSlots[`view-${key}`] || $slots[`view-${key}`]" :name="`view-${key}`" :slot="key" :model="formModel"></slot>
  126 + </template>
  127 + <!-- 表单项具名插槽 -->
  128 + <template v-for="item in _formList">
  129 + <slot v-if="$scopedSlots[`view-item-${item.key}`] || $slots[`view-item-${item.key}`]" :name="`view-item-${item.key}`" :slot="`item-${item.key}`" :model="formModel"></slot>
  130 + </template>
  131 + </eagle-detail>
  132 + <!-- 自定义弹出框内容插槽 -->
  133 + <slot v-else :name="dialogType" :row="tableCurrentRow"></slot>
125 134 </el-dialog>
126 135 </div>
127 136 </template>
... ... @@ -281,6 +290,11 @@ export default {
281 290 this.dialogTitle = '详情';
282 291 this.dialogType = 'dialog-view';
283 292 this.tableCurrentRow = row;
  293 + this.formModel = {};
  294 + // 设置表单值
  295 + Object.keys(row).forEach(key => {
  296 + this.formModel[key] = row[key];
  297 + });
284 298 this.showDialog();
285 299 },
286 300 // 新增按钮
... ... @@ -288,6 +302,7 @@ export default {
288 302 this.dialogTitle = '新增';
289 303 this.dialogType = 'dialog-form';
290 304 this.tableCurrentRow = row;
  305 + this.formModel = {};
291 306 this.showDialog();
292 307 },
293 308 // 编辑按钮
... ... @@ -295,14 +310,12 @@ export default {
295 310 this.dialogTitle = '编辑';
296 311 this.dialogType = 'dialog-form';
297 312 this.tableCurrentRow = row;
298   - this.showDialog();
  313 + this.formModel = {};
299 314 // 设置表单值
300   - this.$nextTick(() => {
301   - Object.keys(row).forEach(key => {
302   - this.formModel[key] = row[key];
303   - });
304   - this.formModel.test = 'test'
  315 + Object.keys(row).forEach(key => {
  316 + this.formModel[key] = row[key];
305 317 });
  318 + this.showDialog();
306 319 },
307 320 // 删除按钮
308 321 handleDelete(type, scope) {
... ... @@ -343,14 +356,12 @@ export default {
343 356 // 隐藏弹出框
344 357 hideDialog() {
345 358 this.dialogVisible = false;
346   - this.$nextTick(() => {
347   - this.tableSelection = [];
348   - this.tableLoading = false;
349   - this.tableCurrentRow = null;
350   - this.formModel = {};
351   - this.dialogTitle = '';
352   - this.dialogType = '';
353   - });
  359 + this.tableSelection = [];
  360 + this.tableLoading = false;
  361 + this.tableCurrentRow = null;
  362 + this.formModel = {};
  363 + this.dialogTitle = '';
  364 + this.dialogType = '';
354 365 },
355 366 // 设置弹出框模式
356 367 setDialog({ title, type }) {
... ...
packages/search/index.vue
... ... @@ -78,6 +78,13 @@ export default {
78 78 collapse: false,
79 79 };
80 80 },
  81 + created() {
  82 + // 初始化表单模型
  83 + this.initModel(this.list);
  84 + },
  85 + mounted() {
  86 + this.setModelValue(this.value);
  87 + },
81 88 computed: {
82 89 visibleColNum() {
83 90 return 24 / this.span;
... ... @@ -86,9 +93,7 @@ export default {
86 93 watch: {
87 94 // 组件外部v-model值更新后同步刷新model
88 95 value(val) {
89   - Object.keys(this.model).forEach(key => {
90   - this.model[key] = val ? val[key] : undefined;
91   - });
  96 + this.setModelValue(val);
92 97 },
93 98 // 配置列表有改动时初始化表单模型
94 99 list(value) {
... ... @@ -102,11 +107,13 @@ export default {
102 107 deep: true
103 108 }
104 109 },
105   - created() {
106   - // 初始化表单模型
107   - this.initModel(this.list);
108   - },
109 110 methods: {
  111 + // 设置表单值
  112 + setModelValue(value) {
  113 + Object.keys(this.model).forEach(key => {
  114 + this.model[key] = value ? value[key] : undefined;
  115 + });
  116 + },
110 117 // 绑定提示组件参数
111 118 bindItemTip(tip) {
112 119 if (typeof tip === 'string') {
... ...
packages/table/index.vue
... ... @@ -41,12 +41,6 @@ export default {
41 41 // 表格事件
42 42 tableEvents: Object,
43 43 },
44   - watch: {
45   - // 组件外部v-model值更新后同步刷新model
46   - value(val) {
47   - this.tableData = val || [];
48   - },
49   - },
50 44 mounted() {
51 45 this.tableData = this.value || [];
52 46 },
... ... @@ -58,6 +52,12 @@ export default {
58 52 }
59 53 }
60 54 },
  55 + watch: {
  56 + // 组件外部v-model值更新后同步刷新model
  57 + value(val) {
  58 + this.tableData = val || [];
  59 + },
  60 + },
61 61 data() {
62 62 return {
63 63 // 表格数据
... ...