Commit 6346896af071322255e3a497a9f9246251ce63c6
1 parent
1c0a5026
Exists in
master
and in
1 other branch
新增scheme组件
Showing
8 changed files
with
229 additions
and
15 deletions
Show diff stats
examples/components/code-snippet.vue
| @@ -47,6 +47,12 @@ export default { | @@ -47,6 +47,12 @@ export default { | ||
| 47 | box-shadow: 0 6px 12px -2px #e6e6e6, 0 0 0 1px #f0f2f7; | 47 | box-shadow: 0 6px 12px -2px #e6e6e6, 0 0 0 1px #f0f2f7; |
| 48 | background-color: #ffffff; | 48 | background-color: #ffffff; |
| 49 | text-align: left; | 49 | text-align: left; |
| 50 | + // element-ui样式冲突 | ||
| 51 | + ul > li { | ||
| 52 | + list-style-type: none; | ||
| 53 | + margin: 0px; | ||
| 54 | + padding: 0px; | ||
| 55 | + } | ||
| 50 | } | 56 | } |
| 51 | .eagle-code-snippet--demo { | 57 | .eagle-code-snippet--demo { |
| 52 | box-sizing: border-box; | 58 | box-sizing: border-box; |
examples/views/docs/scheme.md
| @@ -10,7 +10,17 @@ Scheme是一个数æ®é©±åŠ¨çš„è§£å†³æ–¹æ¡ˆï¼Œé€šè¿‡æ—¢å®šçš„ä¸šåŠ¡é…ç½®å‚æ•°ï¼ | @@ -10,7 +10,17 @@ Scheme是一个数æ®é©±åŠ¨çš„è§£å†³æ–¹æ¡ˆï¼Œé€šè¿‡æ—¢å®šçš„ä¸šåŠ¡é…ç½®å‚æ•°ï¼ | ||
| 10 | 10 | ||
| 11 | ```html | 11 | ```html |
| 12 | <template> | 12 | <template> |
| 13 | - <eagle-scheme :list="schemeList"></eagle-scheme> | 13 | + <eagle-scheme :list="schemeList"> |
| 14 | + <!-- <el-table-column slot="table-append" prop="$operation" label="æ“作" min-width="140"> | ||
| 15 | + <el-button class="eagle-scheme__table-btn" type="text" icon="el-icon-edit" title="编辑"></el-button> | ||
| 16 | + <eagle-confirm class="eagle-scheme__table-btn" title="是å¦åˆ 除?"> | ||
| 17 | + <el-button type="text" icon="el-icon-delete" title="åˆ é™¤"></el-button> | ||
| 18 | + </eagle-confirm> | ||
| 19 | + </el-table-column> --> | ||
| 20 | + <template slot="table-append-btn"> | ||
| 21 | + <el-button class="eagle-scheme__table-btn" type="text" icon="el-icon-view" title="查看"></el-button> | ||
| 22 | + </template> | ||
| 23 | + </eagle-scheme> | ||
| 14 | </template> | 24 | </template> |
| 15 | 25 | ||
| 16 | <script> | 26 | <script> |
| @@ -19,9 +29,10 @@ export default { | @@ -19,9 +29,10 @@ export default { | ||
| 19 | return { | 29 | return { |
| 20 | schemeList: [ | 30 | schemeList: [ |
| 21 | { type: 'el-input', key: 'name', label: 'åç§°', rules: [{ required: true, message: '请输入åç§°' }] }, | 31 | { type: 'el-input', key: 'name', label: 'åç§°', rules: [{ required: true, message: '请输入åç§°' }] }, |
| 22 | - { type: 'eagle-select', key: 'address', label: 'ä½å€', props: { dataSource: [{ label: '大街上', value: 'S' }, { label: 'å°åŒºé‡Œ', value: 'H' }] } }, | ||
| 23 | - { type: 'el-input', key: 'postcode', label: '邮编', span: 12, tip: { content: '邮政编ç ', placement: "left" } }, | ||
| 24 | - { type: 'el-input', key: 'number', label: 'æ¥¼æ ‹å·', span: 12, visible: (model) => model.address === 'H' }, | 32 | + { type: 'el-input', key: 'code', label: 'ç¼–ç ', rules: [{ required: true, message: '请输入编ç ' }], exclude: 'search' }, |
| 33 | + { type: 'el-input', key: 'type', label: '类型' }, | ||
| 34 | + { type: 'el-input-number', key: 'sort', label: '排åº', exclude: 'search' }, | ||
| 35 | + { type: 'el-input', key: 'status', label: '状æ€' }, | ||
| 25 | ] | 36 | ] |
| 26 | } | 37 | } |
| 27 | }, | 38 | }, |
packages/confirm/index.vue
| @@ -15,7 +15,7 @@ | @@ -15,7 +15,7 @@ | ||
| 15 | </style> | 15 | </style> |
| 16 | 16 | ||
| 17 | <template> | 17 | <template> |
| 18 | - <el-popover :placement="placement" :trigger="trigger" v-model="visible"> | 18 | + <el-popover class="eagle-confirm" :placement="placement" :trigger="trigger" v-model="visible"> |
| 19 | <div> | 19 | <div> |
| 20 | <p class="eagle-confirm-title"> | 20 | <p class="eagle-confirm-title"> |
| 21 | <i class="el-icon-info eagle-confirm-icon"></i> | 21 | <i class="el-icon-info eagle-confirm-icon"></i> |
packages/form/index.vue
| @@ -22,14 +22,14 @@ | @@ -22,14 +22,14 @@ | ||
| 22 | <template v-for="(data, index) in listOption.dataList"> | 22 | <template v-for="(data, index) in listOption.dataList"> |
| 23 | <template v-if="listOption.isGroup"> | 23 | <template v-if="listOption.isGroup"> |
| 24 | <slot v-if="$scopedSlots[data.key] || $slots[data.key]" :name="data.key" v-bind="data"></slot> | 24 | <slot v-if="$scopedSlots[data.key] || $slots[data.key]" :name="data.key" v-bind="data"></slot> |
| 25 | - <el-col v-else class="eagle-form__group-title" :key="data.key" :span="24"> | 25 | + <el-col v-else class="eagle-form__group-title" :key="data.key" :span="span"> |
| 26 | <i v-if="data.icon" :class="`el-icon-${data.icon} eagle-form__group-icon`"></i> | 26 | <i v-if="data.icon" :class="`el-icon-${data.icon} eagle-form__group-icon`"></i> |
| 27 | <span>{{ data.label }}</span> | 27 | <span>{{ data.label }}</span> |
| 28 | </el-col> | 28 | </el-col> |
| 29 | </template> | 29 | </template> |
| 30 | <el-row :class="{ 'eagle-form__group-content': listOption.isGroup }" :key="'group-content-' + index" :gutter="15"> | 30 | <el-row :class="{ 'eagle-form__group-content': listOption.isGroup }" :key="'group-content-' + index" :gutter="15"> |
| 31 | <template v-for="(item, index) in data.list"> | 31 | <template v-for="(item, index) in data.list"> |
| 32 | - <el-col v-if="bindItemVisible(item.visible)" v-show="bindItemShow(item.show)" :key="index + 'data'" :span="!item.span ? 24 : item.span"> | 32 | + <el-col v-if="bindItemVisible(item.visible)" v-show="bindItemShow(item.show)" :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" :rules="item.rules"> | 33 | <el-form-item :label="item.label" :label-width="item.label ? undefined : item.labelWidth || '0px'" :prop="item.key" :rules="item.rules"> |
| 34 | <el-tooltip :disabled="!item.tip" v-bind="bindItemTip(item.tip)"> | 34 | <el-tooltip :disabled="!item.tip" v-bind="bindItemTip(item.tip)"> |
| 35 | <slot v-if="$scopedSlots[`item-${item.key}`] || $slots[`item-${item.key}`]" :name="`item-${item.key}`" :model="model" v-bind="item"></slot> | 35 | <slot v-if="$scopedSlots[`item-${item.key}`] || $slots[`item-${item.key}`]" :name="`item-${item.key}`" :model="model" v-bind="item"></slot> |
| @@ -86,6 +86,11 @@ export default { | @@ -86,6 +86,11 @@ export default { | ||
| 86 | footerStyle: { | 86 | footerStyle: { |
| 87 | type: [String, Object], | 87 | type: [String, Object], |
| 88 | default: 'center' | 88 | default: 'center' |
| 89 | + }, | ||
| 90 | + // 表单项占位 | ||
| 91 | + span: { | ||
| 92 | + type: Number, | ||
| 93 | + default: 24 | ||
| 89 | } | 94 | } |
| 90 | }, | 95 | }, |
| 91 | data() { | 96 | data() { |
packages/scheme/index.vue
| @@ -2,29 +2,153 @@ | @@ -2,29 +2,153 @@ | ||
| 2 | .eagle-scheme { | 2 | .eagle-scheme { |
| 3 | padding: 0px; | 3 | padding: 0px; |
| 4 | } | 4 | } |
| 5 | +.eagle-scheme__card { | ||
| 6 | + border: 1px solid #F5F5F5; | ||
| 7 | + border-radius: 2px; | ||
| 8 | + background-color: #fff; | ||
| 9 | + padding: 10px; | ||
| 10 | + transition: all .3s ease; | ||
| 11 | + margin-bottom: 10px; | ||
| 12 | +} | ||
| 13 | +.eagle-scheme__card .eagle-search { | ||
| 14 | + padding-top: 20px; | ||
| 15 | + padding-bottom: 10px; | ||
| 16 | +} | ||
| 17 | +.eagle-scheme__action { | ||
| 18 | + padding-bottom: 10px; | ||
| 19 | +} | ||
| 20 | +.eagle-scheme__table .eagle-scheme__table-btn:not(:first-child) { | ||
| 21 | + padding-left: 10px; | ||
| 22 | + margin-left: 0px; | ||
| 23 | +} | ||
| 24 | +.eagle-scheme__pagination { | ||
| 25 | + text-align: right; | ||
| 26 | + padding-top: 10px; | ||
| 27 | +} | ||
| 5 | </style> | 28 | </style> |
| 6 | 29 | ||
| 7 | <template> | 30 | <template> |
| 8 | <div class="eagle-scheme"> | 31 | <div class="eagle-scheme"> |
| 9 | - Scheme | 32 | + <div class="eagle-scheme__card"> |
| 33 | + <eagle-search :list="_searchList"></eagle-search> | ||
| 34 | + </div> | ||
| 35 | + <div class="eagle-scheme__action"> | ||
| 36 | + <el-button type="primary" size="small" @click="showDialog">新增</el-button> | ||
| 37 | + </div> | ||
| 38 | + <div class="eagle-scheme__table"> | ||
| 39 | + <eagle-table :list="_tableList" :tableProps="tableProps" :value="tableData"> | ||
| 40 | + <template v-if="$scopedSlots['table-append'] || $slots['table-append']"> | ||
| 41 | + <slot name="table-append" slot="append"></slot> | ||
| 42 | + </template> | ||
| 43 | + <template v-else> | ||
| 44 | + <el-table-column slot="append" prop="$operation" label="操作" min-width="140"> | ||
| 45 | + <slot v-if="$scopedSlots['table-append-btn'] || $slots['table-append-btn']" name="table-append-btn"></slot> | ||
| 46 | + <el-button class="eagle-scheme__table-btn" type="text" icon="el-icon-edit" title="编辑" @click="showDialog"></el-button> | ||
| 47 | + <eagle-confirm class="eagle-scheme__table-btn" title="是否删除?"> | ||
| 48 | + <el-button type="text" icon="el-icon-delete" title="删除"></el-button> | ||
| 49 | + </eagle-confirm> | ||
| 50 | + </el-table-column> | ||
| 51 | + </template> | ||
| 52 | + </eagle-table> | ||
| 53 | + <div class="eagle-scheme__pagination"> | ||
| 54 | + <el-pagination size="small" @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="currentPage" | ||
| 55 | + :page-size="100" :total="400" v-bind="paginationProps"></el-pagination> | ||
| 56 | + </div> | ||
| 57 | + </div> | ||
| 58 | + <el-dialog :title="dialogProps.title || '标题'" :visible.sync="dialogVisible" v-bind="dialogProps"> | ||
| 59 | + <eagle-form :list="_formList" :formProps="formProps" :span="12" @cancel="hideDialog"></eagle-form> | ||
| 60 | + </el-dialog> | ||
| 10 | </div> | 61 | </div> |
| 11 | </template> | 62 | </template> |
| 12 | 63 | ||
| 13 | <script> | 64 | <script> |
| 65 | +import { format, objExclude, generateListSpace } from './parser'; | ||
| 66 | + | ||
| 14 | export default { | 67 | export default { |
| 15 | name: 'Scheme', | 68 | name: 'Scheme', |
| 16 | props: { | 69 | props: { |
| 17 | // 配置列表 | 70 | // 配置列表 |
| 18 | - list: { | ||
| 19 | - type: Array, | ||
| 20 | - required: true | 71 | + list: Array, |
| 72 | + // 搜索表单配置 | ||
| 73 | + searchList: Array, | ||
| 74 | + // 表单配置 | ||
| 75 | + formList: Array, | ||
| 76 | + // 表格配置 | ||
| 77 | + tableList: Array, | ||
| 78 | + // 表格参数 | ||
| 79 | + tableProps: { | ||
| 80 | + type: Object, | ||
| 81 | + default() { | ||
| 82 | + return { size: 'small', border: true } | ||
| 83 | + } | ||
| 21 | }, | 84 | }, |
| 85 | + // 表单参数 | ||
| 86 | + formProps: { | ||
| 87 | + type: Object, | ||
| 88 | + default() { | ||
| 89 | + return { size: 'small', 'label-width': '90px' } | ||
| 90 | + } | ||
| 91 | + }, | ||
| 92 | + // 分页参数 | ||
| 93 | + paginationProps: { | ||
| 94 | + type: Object, | ||
| 95 | + default() { | ||
| 96 | + return { 'page-sizes': [10, 20, 50], layout: 'total, sizes, prev, pager, next, jumper' } | ||
| 97 | + } | ||
| 98 | + }, | ||
| 99 | + // 弹出框参数 | ||
| 100 | + dialogProps: { | ||
| 101 | + type: Object, | ||
| 102 | + default() { | ||
| 103 | + return { width: '65%' } | ||
| 104 | + } | ||
| 105 | + } | ||
| 22 | }, | 106 | }, |
| 23 | data() { | 107 | data() { |
| 24 | return { | 108 | return { |
| 25 | - // 编辑器表单模型 | ||
| 26 | - model: {} | 109 | + // 搜索表单配置 |
| 110 | + _searchList: [], | ||
| 111 | + // 表单配置 | ||
| 112 | + _formList: [], | ||
| 113 | + // 表格配置 | ||
| 114 | + _tableList: [], | ||
| 115 | + // 当前页 | ||
| 116 | + currentPage: 1, | ||
| 117 | + // 弹出框状态 | ||
| 118 | + dialogVisible: false, | ||
| 119 | + tableData: [ | ||
| 120 | + { name: '赵伯', code: 'U00001', type: 'admin', sort: 0, status: 'active' }, | ||
| 121 | + { name: '钱仲', code: 'U00002', type: 'user', sort: 1, status: 'active' }, | ||
| 122 | + { name: '孙叔', code: 'U00003', type: 'user', sort: 2, status: 'active' }, | ||
| 123 | + { name: '李季', code: 'U00004', type: 'user', sort: 3, status: 'active' }, | ||
| 124 | + ] | ||
| 27 | }; | 125 | }; |
| 28 | }, | 126 | }, |
| 127 | + created() { | ||
| 128 | + if (this.list instanceof Array) { | ||
| 129 | + const { search = [], form = [], table = [] } = generateListSpace(this.list); | ||
| 130 | + this._searchList = search; | ||
| 131 | + this._formList = form; | ||
| 132 | + this._tableList = table; | ||
| 133 | + } else { | ||
| 134 | + this._searchList = this.searchList || []; | ||
| 135 | + this._formList = this.formList || []; | ||
| 136 | + this._tableList = this.tableList || []; | ||
| 137 | + } | ||
| 138 | + }, | ||
| 139 | + methods: { | ||
| 140 | + showDialog() { | ||
| 141 | + this.dialogVisible = true; | ||
| 142 | + }, | ||
| 143 | + hideDialog() { | ||
| 144 | + this.dialogVisible = false; | ||
| 145 | + }, | ||
| 146 | + handleSizeChange(val) { | ||
| 147 | + console.log(`每页 ${val} 条`); | ||
| 148 | + }, | ||
| 149 | + handleCurrentChange(val) { | ||
| 150 | + console.log(`当前页: ${val}`); | ||
| 151 | + } | ||
| 152 | + } | ||
| 29 | }; | 153 | }; |
| 30 | -</script> | ||
| 31 | \ No newline at end of file | 154 | \ No newline at end of file |
| 155 | +</script> |
| @@ -0,0 +1,67 @@ | @@ -0,0 +1,67 @@ | ||
| 1 | +// 简单格式化掉Vue监听器存于Object中的属性 | ||
| 2 | +export function format(obj) { | ||
| 3 | + return JSON.parse(JSON.stringify(obj)); | ||
| 4 | +} | ||
| 5 | + | ||
| 6 | +// 去除Object中不需要包含的属性 | ||
| 7 | +export function objExclude(obj = {}, exclude = []) { | ||
| 8 | + const result = {}; | ||
| 9 | + Object.keys(obj).forEach((key) => { | ||
| 10 | + if (exclude.indexOf(key) < 0) { | ||
| 11 | + result[key] = obj[key]; | ||
| 12 | + } | ||
| 13 | + }); | ||
| 14 | + return result; | ||
| 15 | +} | ||
| 16 | + | ||
| 17 | +// 默认作用域 | ||
| 18 | +const LIST_SPACE = ['search', 'form', 'table']; | ||
| 19 | + | ||
| 20 | +// 根据配置列表拆分作用域 | ||
| 21 | +export function generateListSpace(fields = []) { | ||
| 22 | + const array = { | ||
| 23 | + search: [], // 搜索表单 | ||
| 24 | + form: [], // 表单 | ||
| 25 | + table: [], // 表格 | ||
| 26 | + }; | ||
| 27 | + fields.forEach((field) => { | ||
| 28 | + // 可以在列表中通过include或exclude设置当前配置的作用域 | ||
| 29 | + const { include = LIST_SPACE, exclude = [] } = field; | ||
| 30 | + // 判断include | ||
| 31 | + let _inclue = []; | ||
| 32 | + if (include instanceof String || typeof include === 'string') { | ||
| 33 | + _inclue = [include]; | ||
| 34 | + } else if (include instanceof Array && typeof include === 'object') { | ||
| 35 | + _inclue = include; | ||
| 36 | + } | ||
| 37 | + // 判断exclude转换为include的情况 | ||
| 38 | + let _exclude_include = []; | ||
| 39 | + if (exclude instanceof String || typeof exclude === 'string') { | ||
| 40 | + _exclude_include = LIST_SPACE.filter(item => item !== exclude); | ||
| 41 | + } else if (exclude instanceof Array && typeof exclude === 'object') { | ||
| 42 | + _exclude_include = LIST_SPACE.filter(item => exclude.indexOf(item) < 0 ); | ||
| 43 | + } | ||
| 44 | + // 作用域交集 | ||
| 45 | + const _intersection = _inclue.filter((v) => { return _exclude_include.indexOf(v) !== -1; }); | ||
| 46 | + // 返回改配置项的作用域 | ||
| 47 | + const _list_space = [...new Set(_intersection)]; | ||
| 48 | + // 将配置项按需分配至各作用域下 | ||
| 49 | + _list_space.forEach((name) => { | ||
| 50 | + if (name === 'search') { | ||
| 51 | + const filterField = objExclude(field, ['rules']); // 默认搜索表单去除校验规则 | ||
| 52 | + array[name].push({ ...filterField, ...(field.$search || {}) }); // 配置列表可通过$search单独为search域做配置 | ||
| 53 | + } else if (name === 'form') { | ||
| 54 | + array[name].push({ ...field, ...(field.$form || {}) }); // 配置列表可通过$form单独为form域做配置 | ||
| 55 | + } else if (name === 'table') { | ||
| 56 | + array[name].push({ ...field, ...(field.$table || {}) }); // 配置列表可通过$table单独为table域做配置 | ||
| 57 | + } | ||
| 58 | + }); | ||
| 59 | + }); | ||
| 60 | + return array; | ||
| 61 | +} | ||
| 62 | + | ||
| 63 | +export default { | ||
| 64 | + format, | ||
| 65 | + objExclude, | ||
| 66 | + generateListSpace, | ||
| 67 | +} | ||
| 0 | \ No newline at end of file | 68 | \ No newline at end of file |
packages/search/index.vue
| @@ -20,7 +20,7 @@ | @@ -20,7 +20,7 @@ | ||
| 20 | </el-form-item> | 20 | </el-form-item> |
| 21 | </el-col> | 21 | </el-col> |
| 22 | </template> | 22 | </template> |
| 23 | - <el-col :span="list.length > visibleColNum ? collapse ? span : 24 : span" class="eagle-search__btn-col"> | 23 | + <el-col :span="list.length >= visibleColNum ? collapse ? span : 24 : span" class="eagle-search__btn-col"> |
| 24 | <slot v-if="$scopedSlots['button-group'] || $slots['button-group']" name="button-group" | 24 | <slot v-if="$scopedSlots['button-group'] || $slots['button-group']" name="button-group" |
| 25 | :model="model" :collapse="collapse" :doSearch="handleSearch" :doReset="handleReset" :doCollapse="handleCollapse" | 25 | :model="model" :collapse="collapse" :doSearch="handleSearch" :doReset="handleReset" :doCollapse="handleCollapse" |
| 26 | ></slot> | 26 | ></slot> |
packages/table/index.vue
| @@ -13,6 +13,7 @@ | @@ -13,6 +13,7 @@ | ||
| 13 | <el-table-column v-else v-bind="item" :prop="item.key" :key="index" :min-width="item.minWidth || '120'"></el-table-column> | 13 | <el-table-column v-else v-bind="item" :prop="item.key" :key="index" :min-width="item.minWidth || '120'"></el-table-column> |
| 14 | </template> | 14 | </template> |
| 15 | </template> | 15 | </template> |
| 16 | + <slot name="append"></slot> | ||
| 16 | </el-table> | 17 | </el-table> |
| 17 | </template> | 18 | </template> |
| 18 | 19 |