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 | 47 | box-shadow: 0 6px 12px -2px #e6e6e6, 0 0 0 1px #f0f2f7; |
| 48 | 48 | background-color: #ffffff; |
| 49 | 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 | 57 | .eagle-code-snippet--demo { |
| 52 | 58 | box-sizing: border-box; | ... | ... |
examples/views/docs/scheme.md
| ... | ... | @@ -10,7 +10,17 @@ Scheme是一个数æ®é©±åŠ¨çš„è§£å†³æ–¹æ¡ˆï¼Œé€šè¿‡æ—¢å®šçš„ä¸šåŠ¡é…ç½®å‚æ•°ï¼ |
| 10 | 10 | |
| 11 | 11 | ```html |
| 12 | 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 | 24 | </template> |
| 15 | 25 | |
| 16 | 26 | <script> |
| ... | ... | @@ -19,9 +29,10 @@ export default { |
| 19 | 29 | return { |
| 20 | 30 | schemeList: [ |
| 21 | 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 | 15 | </style> |
| 16 | 16 | |
| 17 | 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 | 19 | <div> |
| 20 | 20 | <p class="eagle-confirm-title"> |
| 21 | 21 | <i class="el-icon-info eagle-confirm-icon"></i> | ... | ... |
packages/form/index.vue
| ... | ... | @@ -22,14 +22,14 @@ |
| 22 | 22 | <template v-for="(data, index) in listOption.dataList"> |
| 23 | 23 | <template v-if="listOption.isGroup"> |
| 24 | 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 | 26 | <i v-if="data.icon" :class="`el-icon-${data.icon} eagle-form__group-icon`"></i> |
| 27 | 27 | <span>{{ data.label }}</span> |
| 28 | 28 | </el-col> |
| 29 | 29 | </template> |
| 30 | 30 | <el-row :class="{ 'eagle-form__group-content': listOption.isGroup }" :key="'group-content-' + index" :gutter="15"> |
| 31 | 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 | 33 | <el-form-item :label="item.label" :label-width="item.label ? undefined : item.labelWidth || '0px'" :prop="item.key" :rules="item.rules"> |
| 34 | 34 | <el-tooltip :disabled="!item.tip" v-bind="bindItemTip(item.tip)"> |
| 35 | 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 | 86 | footerStyle: { |
| 87 | 87 | type: [String, Object], |
| 88 | 88 | default: 'center' |
| 89 | + }, | |
| 90 | + // 表单项占位 | |
| 91 | + span: { | |
| 92 | + type: Number, | |
| 93 | + default: 24 | |
| 89 | 94 | } |
| 90 | 95 | }, |
| 91 | 96 | data() { | ... | ... |
packages/scheme/index.vue
| ... | ... | @@ -2,29 +2,153 @@ |
| 2 | 2 | .eagle-scheme { |
| 3 | 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 | 28 | </style> |
| 6 | 29 | |
| 7 | 30 | <template> |
| 8 | 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 | 61 | </div> |
| 11 | 62 | </template> |
| 12 | 63 | |
| 13 | 64 | <script> |
| 65 | +import { format, objExclude, generateListSpace } from './parser'; | |
| 66 | + | |
| 14 | 67 | export default { |
| 15 | 68 | name: 'Scheme', |
| 16 | 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 | 107 | data() { |
| 24 | 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 | 154 | \ No newline at end of file |
| 155 | +</script> | ... | ... |
| ... | ... | @@ -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 | 68 | \ No newline at end of file | ... | ... |
packages/search/index.vue
| ... | ... | @@ -20,7 +20,7 @@ |
| 20 | 20 | </el-form-item> |
| 21 | 21 | </el-col> |
| 22 | 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 | 24 | <slot v-if="$scopedSlots['button-group'] || $slots['button-group']" name="button-group" |
| 25 | 25 | :model="model" :collapse="collapse" :doSearch="handleSearch" :doReset="handleReset" :doCollapse="handleCollapse" |
| 26 | 26 | ></slot> | ... | ... |
packages/table/index.vue