Commit 6346896af071322255e3a497a9f9246251ce63c6

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

新增scheme组件

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>
packages/scheme/parser.js 0 → 100644
@@ -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