eoss 0.1.0-alpha.47 → 0.1.0-alpha.49
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/3.js +1 -1
- package/lib/autocomplete.js +6 -6
- package/lib/ca-login.js +2 -2
- package/lib/calendar.js +2 -2
- package/lib/cascader-panel.js +2 -2
- package/lib/cascader.js +4 -4
- package/lib/code-editor.js +2 -2
- package/lib/collapse-item.js +2 -2
- package/lib/collapse.js +2 -2
- package/lib/color-picker.js +2 -2
- package/lib/cron.js +4 -4
- package/lib/data-table.js +366 -20
- package/lib/date-picker.js +3 -3
- package/lib/dialog.js +12 -10
- package/lib/drawer.js +2 -2
- package/lib/dropdown-item.js +23 -4
- package/lib/dropdown.js +4 -4
- package/lib/empty.js +2 -2
- package/lib/eoss.common.js +734 -322
- package/lib/flow-group.js +2 -2
- package/lib/flow.js +7 -7
- package/lib/form-editor.js +2 -2
- package/lib/form.js +12 -11
- package/lib/guide.js +2 -2
- package/lib/icons.js +4 -4
- package/lib/index.js +1 -1
- package/lib/input.js +2 -2
- package/lib/loading.js +4 -4
- package/lib/lowcode-view.js +2 -2
- package/lib/lowcode.js +7 -50
- package/lib/main.js +5 -5
- package/lib/menu-item-group.js +5 -1
- package/lib/menu.js +33 -43
- package/lib/message-box.js +4 -4
- package/lib/message.js +2 -2
- package/lib/notification.js +2 -2
- package/lib/pagination.js +2 -2
- package/lib/process-module.js +2 -2
- package/lib/rate.js +2 -2
- package/lib/scrollbar.js +71 -87
- package/lib/select.js +23 -13
- package/lib/selector-panel.js +2 -2
- package/lib/selector.js +16 -18
- package/lib/slider.js +2 -2
- package/lib/step.js +2 -2
- package/lib/steps.js +4 -4
- package/lib/submenu.js +16 -24
- package/lib/switch.js +2 -2
- package/lib/table-column.js +69 -3
- package/lib/table.js +162 -56
- package/lib/tabs.js +2 -2
- package/lib/theme-chalk/autocomplete.css +1 -1
- package/lib/theme-chalk/cascader-panel.css +1 -1
- package/lib/theme-chalk/cascader.css +1 -1
- package/lib/theme-chalk/data-table.css +1 -1
- package/lib/theme-chalk/date-picker.css +1 -1
- package/lib/theme-chalk/form.css +1 -1
- package/lib/theme-chalk/index.css +1 -1
- package/lib/theme-chalk/input-number.css +1 -1
- package/lib/theme-chalk/input.css +1 -1
- package/lib/theme-chalk/menu.css +1 -1
- package/lib/theme-chalk/message-box.css +1 -1
- package/lib/theme-chalk/pagination.css +1 -1
- package/lib/theme-chalk/scrollbar.css +1 -1
- package/lib/theme-chalk/select.css +1 -1
- package/lib/theme-chalk/selector.css +1 -1
- package/lib/theme-chalk/slider.css +1 -1
- package/lib/theme-chalk/table.css +1 -1
- package/lib/theme-chalk/time-picker.css +1 -1
- package/lib/theme-chalk/time-select.css +1 -1
- package/lib/theme-chalk/transfer.css +1 -1
- package/lib/theme-chalk/tree.css +1 -1
- package/lib/theme-chalk/upload.css +1 -1
- package/lib/time-picker.js +2 -2
- package/lib/time-select.js +6 -6
- package/lib/toolbar.js +2 -2
- package/lib/transfer.js +4 -4
- package/lib/tree.js +8 -15
- package/lib/upload.js +20 -20
- package/lib/utils/popup/popup-manager.js +24 -8
- package/package.json +4 -1
- package/packages/data-table/src/data-table.vue +43 -8
- package/packages/data-table/src/sizer.vue +104 -87
- package/packages/dialog/src/dialog.vue +4 -2
- package/packages/dropdown/src/dropdown-item.vue +21 -3
- package/packages/form/src/form.vue +5 -8
- package/packages/icons/src/icons.vue +2 -2
- package/packages/lowcode/src/util/components.js +0 -59
- package/packages/menu/src/menu.vue +7 -21
- package/packages/menu/src/mixins.js +6 -1
- package/packages/menu/src/submenu.vue +7 -16
- package/packages/scrollbar/src/main.js +64 -78
- package/packages/select/src/select.vue +13 -6
- package/packages/selector/src/selector.vue +6 -13
- package/packages/table/src/config.js +48 -0
- package/packages/table/src/store/index.js +19 -4
- package/packages/table/src/store/watcher.js +14 -3
- package/packages/table/src/table-body.js +9 -4
- package/packages/table/src/table-column.js +17 -3
- package/packages/table/src/table-footer.js +4 -2
- package/packages/table/src/table-header.js +9 -6
- package/packages/table/src/table.vue +48 -27
- package/packages/theme-chalk/src/data-table.scss +4 -0
- package/packages/theme-chalk/src/form.scss +3 -0
- package/packages/theme-chalk/src/input.scss +2 -2
- package/packages/theme-chalk/src/menu.scss +8 -0
- package/packages/theme-chalk/src/mixins/function.scss +61 -12
- package/packages/theme-chalk/src/mixins/utils.scss +12 -0
- package/packages/theme-chalk/src/scrollbar.scss +4 -5
- package/packages/theme-chalk/src/selector.scss +6 -1
- package/packages/theme-chalk/src/table.scss +40 -0
- package/packages/theme-chalk/src/tree.scss +7 -6
- package/packages/theme-chalk/src/upload.scss +5 -0
- package/packages/tree/src/tree.vue +2 -13
- package/packages/upload/src/upload-list.vue +5 -10
- package/src/index.js +1 -1
- package/src/utils/popup/popup-manager.js +24 -9
|
@@ -8,22 +8,51 @@ import {
|
|
|
8
8
|
addResizeListener,
|
|
9
9
|
removeResizeListener
|
|
10
10
|
} from 'eoss/src/utils/resize-event';
|
|
11
|
-
import { getScrollbarWidth } from 'eoss/src/utils/scrollbar';
|
|
12
|
-
import { toObject } from 'eoss/src/utils/util';
|
|
13
11
|
import Bar from 'eoss/src/components/bar';
|
|
12
|
+
import { toObject } from 'eoss/src/utils/util';
|
|
14
13
|
import ScrollMixin from './scroll-mixin';
|
|
15
14
|
|
|
16
|
-
//
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
15
|
+
// 数字或纯数字字符串补 px,其余形式(100%、inherit 等)原样透传
|
|
16
|
+
function toCssSize(val) {
|
|
17
|
+
const str = String(val).trim();
|
|
18
|
+
return /^-?\d+(\.\d+)?$/.test(str) ? str + 'px' : str;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// 把 'a: b; c-d: e' 形式的样式串解析成驼峰对象
|
|
22
|
+
function parseStyleText(styleText) {
|
|
23
|
+
const res = {};
|
|
24
|
+
const list = String(styleText || '').split(';');
|
|
25
|
+
for (let i = 0; i < list.length; i++) {
|
|
26
|
+
const item = list[i];
|
|
27
|
+
const index = item.indexOf(':');
|
|
28
|
+
if (index < 0) continue;
|
|
29
|
+
const key = item.slice(0, index).trim();
|
|
30
|
+
if (!key) continue;
|
|
31
|
+
res[key.replace(/-(\w)/g, (match, letter) => letter.toUpperCase())] = item.slice(index + 1).trim();
|
|
32
|
+
}
|
|
33
|
+
return res;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// wrap-style 可以是 String / Object / Array,统一归一化成新对象:
|
|
37
|
+
// Vue 2 仅解析绑定为字符串的顶层 style,数组里的字符串项会被丢掉,
|
|
38
|
+
// 另外也不能直接在传入的对象上写字段,避免变更 prop
|
|
39
|
+
function normalizeWrapStyle(val) {
|
|
40
|
+
if (typeof val === 'string') {
|
|
41
|
+
return parseStyleText(val);
|
|
42
|
+
}
|
|
43
|
+
if (Array.isArray(val)) {
|
|
44
|
+
return toObject(val.map((item) => {
|
|
45
|
+
return typeof item === 'string' ? parseStyleText(item) : item || {};
|
|
46
|
+
}));
|
|
25
47
|
}
|
|
26
|
-
|
|
48
|
+
const res = {};
|
|
49
|
+
const source = val || {};
|
|
50
|
+
for (const key in source) {
|
|
51
|
+
if (Object.prototype.hasOwnProperty.call(source, key)) {
|
|
52
|
+
res[key] = source[key];
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return res;
|
|
27
56
|
}
|
|
28
57
|
|
|
29
58
|
/* istanbul ignore next */
|
|
@@ -118,7 +147,6 @@ export default {
|
|
|
118
147
|
sizeHeight: '0',
|
|
119
148
|
moveX: 0,
|
|
120
149
|
moveY: 0,
|
|
121
|
-
height: null,
|
|
122
150
|
initialized: false,
|
|
123
151
|
isHovering: false,
|
|
124
152
|
hideTimer: null,
|
|
@@ -152,47 +180,27 @@ export default {
|
|
|
152
180
|
}
|
|
153
181
|
},
|
|
154
182
|
|
|
155
|
-
// 在 render 方法中使用缓存
|
|
156
183
|
render(h) {
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
if (maxHeight === '100%') {
|
|
173
|
-
gutterStyle += `max-height:calc(100% + ${gutter}px);`;
|
|
174
|
-
} else {
|
|
175
|
-
gutterStyle += maxHeight ? 'max-height:' + parseInt(maxHeight, 10) + 'px' : '';
|
|
176
|
-
}
|
|
177
|
-
} else {
|
|
178
|
-
gutterStyle += `height:calc(100% + ${gutter}px);`;
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
if (Array.isArray(this.wrapStyle)) {
|
|
182
|
-
style = toObject(this.wrapStyle);
|
|
183
|
-
style.marginRight = style.marginBottom = gutterWith;
|
|
184
|
-
if (!style.height && !style.maxHeight) {
|
|
185
|
-
style.height = '100%';
|
|
186
|
-
}
|
|
187
|
-
} else if (typeof this.wrapStyle === 'string') {
|
|
188
|
-
style += gutterStyle;
|
|
189
|
-
} else {
|
|
190
|
-
style = gutterStyle;
|
|
191
|
-
}
|
|
192
|
-
} else {
|
|
193
|
-
style = 'height:100%;';
|
|
184
|
+
// wrap 内联样式只负责高度声明与自定义样式,不再做原生滚动条的占位补偿:
|
|
185
|
+
// 原生滚动条已由 CSS 隐藏(--hidden-default 恒挂,IE 走 -ms-overflow-style),
|
|
186
|
+
// 本身不占位;此前的负 margin + calc(100% + gutter) 在浏览器缩放时,量取的
|
|
187
|
+
// gutter 取整宽度和实际渲染宽度对不上,底部/右侧就会露出一条灰边。
|
|
188
|
+
const wrapStyles = normalizeWrapStyle(this.wrapStyle);
|
|
189
|
+
const height = this.styles && this.styles.height;
|
|
190
|
+
const maxHeight = this.maxHeight ||
|
|
191
|
+
(this.styles && (this.styles.maxHeight || this.styles['max-height']));
|
|
192
|
+
|
|
193
|
+
// 已有的键不覆盖,保证用户显式写的 wrap-style 优先
|
|
194
|
+
if (height && wrapStyles.height === undefined) {
|
|
195
|
+
wrapStyles.height = toCssSize(height);
|
|
196
|
+
}
|
|
197
|
+
if (maxHeight && wrapStyles.maxHeight === undefined) {
|
|
198
|
+
wrapStyles.maxHeight = toCssSize(maxHeight);
|
|
194
199
|
}
|
|
195
200
|
|
|
201
|
+
const hasStyle = Object.keys(wrapStyles).length > 0;
|
|
202
|
+
const style = hasStyle ? wrapStyles : undefined;
|
|
203
|
+
|
|
196
204
|
// 虚拟滚动实现
|
|
197
205
|
const view = h(
|
|
198
206
|
this.tag,
|
|
@@ -211,8 +219,7 @@ export default {
|
|
|
211
219
|
onScroll={this.handleScroll}
|
|
212
220
|
class={[
|
|
213
221
|
this.wrapClass,
|
|
214
|
-
'es-scrollbar__wrap'
|
|
215
|
-
gutter ? '' : 'es-scrollbar__wrap--hidden-default'
|
|
222
|
+
'es-scrollbar__wrap es-scrollbar__wrap--hidden-default'
|
|
216
223
|
]}
|
|
217
224
|
>
|
|
218
225
|
{[view]}
|
|
@@ -245,8 +252,9 @@ export default {
|
|
|
245
252
|
nodes = [
|
|
246
253
|
<div
|
|
247
254
|
ref="wrap"
|
|
248
|
-
class={[this.wrapClass, 'es-scrollbar__wrap']}
|
|
249
255
|
style={style}
|
|
256
|
+
onScroll={this.handleScroll}
|
|
257
|
+
class={[this.wrapClass, 'es-scrollbar__wrap']}
|
|
250
258
|
>
|
|
251
259
|
{[view]}
|
|
252
260
|
</div>
|
|
@@ -571,18 +579,8 @@ export default {
|
|
|
571
579
|
const wrap = this.wrap;
|
|
572
580
|
if (!wrap) return;
|
|
573
581
|
|
|
574
|
-
//
|
|
575
|
-
|
|
576
|
-
// 如果没有设置高度,尝试从父元素获取
|
|
577
|
-
const parent = wrap.parentNode;
|
|
578
|
-
if (parent && parent.style.height) {
|
|
579
|
-
wrap.style.height = parent.style.height;
|
|
580
|
-
} else if (parent && parent.style.maxHeight) {
|
|
581
|
-
wrap.style.height = parent.style.maxHeight;
|
|
582
|
-
} else if (parent && parent.clientHeight) {
|
|
583
|
-
wrap.style.height = parent.clientHeight + 'px';
|
|
584
|
-
}
|
|
585
|
-
}
|
|
582
|
+
// wrap 高度:CSS 给默认的 height: 100%,需要限高时由调用方通过
|
|
583
|
+
// max-height / wrap-style 声明(组件自身的 wrap-class 限高不受干扰)
|
|
586
584
|
|
|
587
585
|
// 缓存计算值
|
|
588
586
|
const clientHeight = wrap.clientHeight;
|
|
@@ -603,18 +601,6 @@ export default {
|
|
|
603
601
|
}
|
|
604
602
|
|
|
605
603
|
this.onReady && this.onReady(this.sizeHeight, this.sizeWidth);
|
|
606
|
-
|
|
607
|
-
// 延迟执行高度计算逻辑
|
|
608
|
-
requestAnimationFrame(() => {
|
|
609
|
-
let maxH = wrap.parentNode.style['max-height'];
|
|
610
|
-
if (maxH) {
|
|
611
|
-
maxH = parseInt(maxH, 10);
|
|
612
|
-
let gutter = getCachedScrollbarWidth();
|
|
613
|
-
if (wrap.offsetHeight - gutter > maxH) {
|
|
614
|
-
this.height = maxH;
|
|
615
|
-
}
|
|
616
|
-
}
|
|
617
|
-
});
|
|
618
604
|
});
|
|
619
605
|
},
|
|
620
606
|
|
|
@@ -1100,6 +1100,10 @@ export default {
|
|
|
1100
1100
|
},
|
|
1101
1101
|
|
|
1102
1102
|
results: {
|
|
1103
|
+
// 树形模式的 options 完全由 data/results 驱动(树节点不是 es-option,不会自注册),
|
|
1104
|
+
// 必须 immediate:否则静态传入 data 时 results 初始化不触发 watcher,
|
|
1105
|
+
// options 恒为 [],下拉被 v-show="options.length > 0" 隐藏并显示「无数据」
|
|
1106
|
+
immediate: true,
|
|
1103
1107
|
deep: true,
|
|
1104
1108
|
handler(val) {
|
|
1105
1109
|
if (this.tree) {
|
|
@@ -1726,14 +1730,17 @@ export default {
|
|
|
1726
1730
|
if (this.filterable) this.$refs.input.focus();
|
|
1727
1731
|
this.resetInputHeight();
|
|
1728
1732
|
} else {
|
|
1733
|
+
let selectValue = option.value;
|
|
1729
1734
|
if (this.valueType === 'string') {
|
|
1730
|
-
this
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1735
|
+
selectValue = getValueByPath(option.value, this.actualValueKey);
|
|
1736
|
+
// 树节点未提供 value-key 对应字段时取值为 undefined,直接写入 v-model 会让
|
|
1737
|
+
// setSelected 解析不出 label(表现为选中后不回显),此处退回整节点对象,
|
|
1738
|
+
// 由 getOption 的对象分支按 label-key 取标签
|
|
1739
|
+
if (this.tree && selectValue === undefined) {
|
|
1740
|
+
selectValue = option.value;
|
|
1741
|
+
}
|
|
1736
1742
|
}
|
|
1743
|
+
this.$emit('input', selectValue);
|
|
1737
1744
|
this.emitChange(option.value);
|
|
1738
1745
|
this.visible = false;
|
|
1739
1746
|
}
|
|
@@ -202,11 +202,7 @@ import {
|
|
|
202
202
|
addResizeListener,
|
|
203
203
|
removeResizeListener
|
|
204
204
|
} from 'eoss/src/utils/resize-event';
|
|
205
|
-
import {
|
|
206
|
-
getScrollbarWidth,
|
|
207
|
-
getScrollSize,
|
|
208
|
-
scrollMove
|
|
209
|
-
} from 'eoss/src/utils/scrollbar';
|
|
205
|
+
import { getScrollSize, scrollMove } from 'eoss/src/utils/scrollbar';
|
|
210
206
|
export default {
|
|
211
207
|
name: 'EsSelector',
|
|
212
208
|
inheritAttrs: false,
|
|
@@ -590,8 +586,7 @@ export default {
|
|
|
590
586
|
timer: null,
|
|
591
587
|
tagsHeight: 0,
|
|
592
588
|
moveTo: 0,
|
|
593
|
-
barSize: 0
|
|
594
|
-
scrollbarWidth: 0
|
|
589
|
+
barSize: 0
|
|
595
590
|
};
|
|
596
591
|
},
|
|
597
592
|
computed: {
|
|
@@ -600,13 +595,12 @@ export default {
|
|
|
600
595
|
? { 'max-height': this.tagsHeight + 'px', overflow: 'hidden' }
|
|
601
596
|
: {};
|
|
602
597
|
},
|
|
598
|
+
// tags 折叠限高时内层容器自身滚动,原生条由 CSS 隐藏(见 selector.scss),
|
|
599
|
+
// 不占位也就无需按条宽加宽容器把它推出去——那样在浏览器缩放时量到的
|
|
600
|
+
// 15px 和实际渲染宽度对不上,右侧会露出一条灰边
|
|
603
601
|
tagsStyle() {
|
|
604
602
|
return this.tagsHeight
|
|
605
|
-
? {
|
|
606
|
-
'max-height': this.tagsHeight + 'px',
|
|
607
|
-
overflowY: 'scroll',
|
|
608
|
-
width: `calc(100% + ${this.scrollbarWidth}px)`
|
|
609
|
-
}
|
|
603
|
+
? { 'max-height': this.tagsHeight + 'px', overflowY: 'scroll' }
|
|
610
604
|
: {};
|
|
611
605
|
},
|
|
612
606
|
// 滚动容器
|
|
@@ -732,7 +726,6 @@ export default {
|
|
|
732
726
|
this.mix && this.getSysParam();
|
|
733
727
|
},
|
|
734
728
|
mounted() {
|
|
735
|
-
this.scrollbarWidth = getScrollbarWidth();
|
|
736
729
|
//this.resetInputHeight();
|
|
737
730
|
if (this.filterable) {
|
|
738
731
|
this.$nextTick(() => {
|
|
@@ -24,6 +24,13 @@ export const cellStarts = {
|
|
|
24
24
|
minWidth: 48,
|
|
25
25
|
realWidth: 48,
|
|
26
26
|
order: ''
|
|
27
|
+
},
|
|
28
|
+
drag: {
|
|
29
|
+
width: 48,
|
|
30
|
+
minWidth: 48,
|
|
31
|
+
realWidth: 48,
|
|
32
|
+
order: '',
|
|
33
|
+
className: 'es-table__drag-column'
|
|
27
34
|
}
|
|
28
35
|
};
|
|
29
36
|
|
|
@@ -147,6 +154,47 @@ export const cellForced = {
|
|
|
147
154
|
sortable: false,
|
|
148
155
|
resizable: false,
|
|
149
156
|
className: 'es-table__expand-column'
|
|
157
|
+
},
|
|
158
|
+
|
|
159
|
+
drag: {
|
|
160
|
+
/**
|
|
161
|
+
* 拖拽列默认不渲染表头文案
|
|
162
|
+
* @param {Function} h - createElement函数
|
|
163
|
+
* @param {Object} options - 包含列配置的对象
|
|
164
|
+
* @returns {VNode} Vue虚拟节点
|
|
165
|
+
*/
|
|
166
|
+
renderHeader: function(h, { column }) {
|
|
167
|
+
return column.label || '';
|
|
168
|
+
},
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* 渲染拖拽手柄图标:这一列存在即代表开启行拖拽排序(见 table.vue 的
|
|
172
|
+
* dragEnabled),Sortable 的 handle 指向 es-table__drag-handle。
|
|
173
|
+
* rules 为函数时按行判定(返回假值该行不可拖),rules 显式为 false 时
|
|
174
|
+
* 整列不可拖;不可拖时不给手柄类,Sortable 自然拖不动该行
|
|
175
|
+
* @param {Function} h - createElement函数
|
|
176
|
+
* @param {Object} options - 包含行数据、列配置等的对象
|
|
177
|
+
* @returns {VNode} Vue虚拟节点
|
|
178
|
+
*/
|
|
179
|
+
renderCell: function(h, { row, column, $index, store }) {
|
|
180
|
+
const rules = column.rules;
|
|
181
|
+
const byRules =
|
|
182
|
+
typeof rules === 'function'
|
|
183
|
+
? rules(row, { row, column, $index, store }) !== false
|
|
184
|
+
: rules !== false;
|
|
185
|
+
// 行数据 fixed 为 true 的行本来就不可拖(tr 上的 drag-sort-disabled
|
|
186
|
+
// 会被 Sortable 的 filter 拦掉),图标同步置灰
|
|
187
|
+
const enabled = byRules && !(row && row.fixed);
|
|
188
|
+
const classes = ['es-icon-tuozhuai'];
|
|
189
|
+
if (enabled) {
|
|
190
|
+
classes.push('es-table__drag-handle');
|
|
191
|
+
} else {
|
|
192
|
+
classes.push('is-disabled');
|
|
193
|
+
}
|
|
194
|
+
return <i class={ classes } />;
|
|
195
|
+
},
|
|
196
|
+
sortable: false,
|
|
197
|
+
resizable: false
|
|
150
198
|
}
|
|
151
199
|
};
|
|
152
200
|
|
|
@@ -126,7 +126,12 @@ Watcher.prototype.mutations = {
|
|
|
126
126
|
const columnId =
|
|
127
127
|
'es-table_1_column_' + Math.floor(Math.random() * 10000);
|
|
128
128
|
let column = null;
|
|
129
|
-
if (
|
|
129
|
+
if (
|
|
130
|
+
type === 'selection' ||
|
|
131
|
+
type === 'index' ||
|
|
132
|
+
type === 'expand' ||
|
|
133
|
+
type === 'drag'
|
|
134
|
+
) {
|
|
130
135
|
column = {
|
|
131
136
|
id: columnId,
|
|
132
137
|
type: type,
|
|
@@ -135,7 +140,9 @@ Watcher.prototype.mutations = {
|
|
|
135
140
|
property: _field,
|
|
136
141
|
...cellStarts[type],
|
|
137
142
|
...normalized,
|
|
138
|
-
...config
|
|
143
|
+
...config,
|
|
144
|
+
// drag 列用 rules 控制行是否可拖(见 config.js)
|
|
145
|
+
rules
|
|
139
146
|
};
|
|
140
147
|
} else {
|
|
141
148
|
column = {
|
|
@@ -145,7 +152,9 @@ Watcher.prototype.mutations = {
|
|
|
145
152
|
property: _field,
|
|
146
153
|
formatter,
|
|
147
154
|
...normalized,
|
|
148
|
-
required: _required
|
|
155
|
+
required: _required,
|
|
156
|
+
// 保留 rules 到列对象:drag 列用它控制行是否可拖(见 config.js)
|
|
157
|
+
rules
|
|
149
158
|
};
|
|
150
159
|
}
|
|
151
160
|
let childrens = null;
|
|
@@ -391,7 +400,8 @@ Watcher.prototype.mutations = {
|
|
|
391
400
|
} else if (
|
|
392
401
|
type === 'selection' ||
|
|
393
402
|
type === 'index' ||
|
|
394
|
-
type === 'expand'
|
|
403
|
+
type === 'expand' ||
|
|
404
|
+
type === 'drag'
|
|
395
405
|
) {
|
|
396
406
|
// 特殊类型列不设置默认 renderCell,由 setColumnRenders 套用 cellForced 中的强制渲染函数
|
|
397
407
|
} else {
|
|
@@ -496,6 +506,11 @@ Watcher.prototype.mutations = {
|
|
|
496
506
|
|
|
497
507
|
states._columns = createColumns(thead);
|
|
498
508
|
this.updateColumns();
|
|
509
|
+
// 换 thead 后列对象全部新建、realWidth 为空,若不重排布局,
|
|
510
|
+
// 表头与表体 colgroup 会各自按内容回退自动表格布局,列宽错位(sizer 确认改表头后必现)
|
|
511
|
+
if (this.table && this.table.$ready) {
|
|
512
|
+
this.scheduleLayout();
|
|
513
|
+
}
|
|
499
514
|
},
|
|
500
515
|
|
|
501
516
|
/**
|
|
@@ -109,7 +109,10 @@ export default Vue.extend({
|
|
|
109
109
|
*/
|
|
110
110
|
updateColumns() {
|
|
111
111
|
const states = this.states;
|
|
112
|
-
|
|
112
|
+
// hide 是「是否隐藏列」的列级契约(文档 thead 列配置):隐藏列不参与
|
|
113
|
+
// 渲染与布局,在列构建入口统一剔除,首屏与运行中换 thead(setThead)
|
|
114
|
+
// 都经这一条路径生效;states._columns 仍保留全量供增删列等操作使用
|
|
115
|
+
const _columns = (states._columns || []).filter(column => !column.hide);
|
|
113
116
|
|
|
114
117
|
// 计算固定列和右侧固定列
|
|
115
118
|
states.fixedColumns = _columns.filter(column => column.fixed === true || column.fixed === 'left');
|
|
@@ -121,9 +124,15 @@ export default Vue.extend({
|
|
|
121
124
|
states.fixedColumns.unshift(_columns[0]);
|
|
122
125
|
}
|
|
123
126
|
|
|
127
|
+
// 开启拖拽排序时左右固定层不渲染(见 table.vue 的 dragEnabled),fixed 不生效,
|
|
128
|
+
// 也就不做「固定列前置」重排,保持声明顺序,避免列序被静默打乱
|
|
129
|
+
const dragEnabled = _columns.some(column => column.type === 'drag');
|
|
130
|
+
|
|
124
131
|
// 计算非固定列并生成原始列配置
|
|
125
132
|
const notFixedColumns = _columns.filter(column => !column.fixed);
|
|
126
|
-
states.originColumns =
|
|
133
|
+
states.originColumns = dragEnabled
|
|
134
|
+
? [..._columns]
|
|
135
|
+
: [...states.fixedColumns, ...notFixedColumns, ...states.rightFixedColumns];
|
|
127
136
|
|
|
128
137
|
// 扁平化各类列配置
|
|
129
138
|
const leafColumns = doFlattenColumns(notFixedColumns);
|
|
@@ -136,7 +145,9 @@ export default Vue.extend({
|
|
|
136
145
|
states.rightFixedLeafColumnsLength = rightFixedLeafColumns.length;
|
|
137
146
|
|
|
138
147
|
// 生成最终的列配置和复杂度标记
|
|
139
|
-
states.columns =
|
|
148
|
+
states.columns = dragEnabled
|
|
149
|
+
? doFlattenColumns(_columns)
|
|
150
|
+
: [...fixedLeafColumns, ...leafColumns, ...rightFixedLeafColumns];
|
|
140
151
|
states.isComplex = states.fixedColumns.length > 0 || states.rightFixedColumns.length > 0;
|
|
141
152
|
},
|
|
142
153
|
|
|
@@ -109,8 +109,8 @@ export default {
|
|
|
109
109
|
});
|
|
110
110
|
},
|
|
111
111
|
|
|
112
|
-
//
|
|
113
|
-
'
|
|
112
|
+
// 监听拖拽列(type: 'drag')的增删,有则开启拖拽排序
|
|
113
|
+
'table.dragEnabled'(val) {
|
|
114
114
|
if (val) {
|
|
115
115
|
this.initSortable();
|
|
116
116
|
} else {
|
|
@@ -133,7 +133,7 @@ export default {
|
|
|
133
133
|
},
|
|
134
134
|
|
|
135
135
|
mounted() {
|
|
136
|
-
if (this
|
|
136
|
+
if (this.table.dragEnabled) {
|
|
137
137
|
this.initSortable();
|
|
138
138
|
}
|
|
139
139
|
},
|
|
@@ -156,7 +156,9 @@ export default {
|
|
|
156
156
|
this.$nextTick(() => {
|
|
157
157
|
try {
|
|
158
158
|
this._sortable = new Sortable(this.$refs.dragSort, {
|
|
159
|
-
|
|
159
|
+
// 手柄就是拖拽列里的图标;不可拖的行(rules 判定为假、
|
|
160
|
+
// 或行数据 fixed 为 true)不带这个类,因此拖不动
|
|
161
|
+
handle: '.es-table__drag-handle',
|
|
160
162
|
animation: 150,
|
|
161
163
|
onUpdate: this.handleUpdate,
|
|
162
164
|
filter: '.drag-sort-disabled'
|
|
@@ -203,6 +205,9 @@ export default {
|
|
|
203
205
|
} else if (this.fixed === 'right') {
|
|
204
206
|
return index < this.columnsCount - this.rightFixedLeafCount;
|
|
205
207
|
} else {
|
|
208
|
+
// 开启拖拽排序时左右固定层不渲染(见 table.vue 的 dragEnabled),
|
|
209
|
+
// 固定列只能靠主表显示,不能再用 is-hidden 藏起来
|
|
210
|
+
if (this.table.dragEnabled) return false;
|
|
206
211
|
return (index < this.leftFixedLeafCount) || (index >= this.columnsCount - this.rightFixedLeafCount);
|
|
207
212
|
}
|
|
208
213
|
},
|
|
@@ -25,7 +25,19 @@ export default {
|
|
|
25
25
|
type: String,
|
|
26
26
|
default: 'default'
|
|
27
27
|
},
|
|
28
|
-
|
|
28
|
+
/**
|
|
29
|
+
* 列的规则;type 为 drag 时用它判定行是否可拖:
|
|
30
|
+
* 函数按行判定(返回 false 该行不可拖),false 表示整列不可拖。
|
|
31
|
+
* 必须显式写 default: undefined:类型里带 Boolean 时,Vue 会把未传的
|
|
32
|
+
* 值铸成 false,那就等于默认把整列拖拽关掉了
|
|
33
|
+
* @type {Function|Boolean|Array|Object}
|
|
34
|
+
*/
|
|
35
|
+
rules: {
|
|
36
|
+
type: [Function, Boolean, Array, Object],
|
|
37
|
+
default: undefined
|
|
38
|
+
},
|
|
39
|
+
// Boolean 必须在 String 前:裸写 filterColumn 时 Vue 才会把空串铸成 true(同 sortable 的约定)
|
|
40
|
+
filterColumn: [Boolean, String],
|
|
29
41
|
label: String,
|
|
30
42
|
labelKey: String,
|
|
31
43
|
valueKey: String,
|
|
@@ -393,11 +405,13 @@ export default {
|
|
|
393
405
|
filterPlacement: '',
|
|
394
406
|
isColumnGroup: false,
|
|
395
407
|
filterOpened: false,
|
|
396
|
-
|
|
408
|
+
filterColumn: this.filterColumn,
|
|
397
409
|
// 排序相关属性
|
|
398
410
|
sortable: sortable,
|
|
399
411
|
// 索引列
|
|
400
|
-
index: this.index
|
|
412
|
+
index: this.index,
|
|
413
|
+
// drag 列用它控制行是否可拖(见 config.js 的 cellForced.drag)
|
|
414
|
+
rules: this.rules
|
|
401
415
|
};
|
|
402
416
|
|
|
403
417
|
// 收集不同类型的属性
|
|
@@ -284,9 +284,11 @@ export default {
|
|
|
284
284
|
}
|
|
285
285
|
return before < this.columnsCount - this.rightFixedLeafCount;
|
|
286
286
|
} else if (!this.fixed && column && column.fixed) {
|
|
287
|
-
//
|
|
288
|
-
|
|
287
|
+
// 当页脚实例不固定而列固定时隐藏单元格;
|
|
288
|
+
// 开启拖拽排序时固定层不渲染,固定列要留在主表里显示
|
|
289
|
+
return !this.table.dragEnabled;
|
|
289
290
|
} else {
|
|
291
|
+
if (this.table.dragEnabled) return false;
|
|
290
292
|
return (index < this.leftFixedCount) || (index >= this.columnsCount - this.rightFixedCount);
|
|
291
293
|
}
|
|
292
294
|
},
|
|
@@ -164,7 +164,7 @@ export default {
|
|
|
164
164
|
]}
|
|
165
165
|
>
|
|
166
166
|
{/* 渲染过滤图标 */}
|
|
167
|
-
{this.
|
|
167
|
+
{this._renderfilterColumn(h, column)}
|
|
168
168
|
|
|
169
169
|
{/* 渲染列标题 */}
|
|
170
170
|
{this._renderColumnLabel(h, cellIndex, column)}
|
|
@@ -312,6 +312,8 @@ export default {
|
|
|
312
312
|
} else if (this.fixed === 'right') {
|
|
313
313
|
return start < this.columnsCount - this.rightFixedLeafCount;
|
|
314
314
|
} else {
|
|
315
|
+
// 开启拖拽排序时左右固定层不渲染,固定列表头只能靠主表显示
|
|
316
|
+
if (this.table.dragEnabled) return false;
|
|
315
317
|
return (
|
|
316
318
|
after < this.leftFixedLeafCount ||
|
|
317
319
|
start >= this.columnsCount - this.rightFixedLeafCount
|
|
@@ -483,7 +485,8 @@ export default {
|
|
|
483
485
|
* @param {Event} event - 事件对象
|
|
484
486
|
* @param {Object} column - 列配置
|
|
485
487
|
*/
|
|
486
|
-
|
|
488
|
+
handlefilterColumnumn(event, column) {
|
|
489
|
+
console.log('filter-column');
|
|
487
490
|
if (this.$parent) {
|
|
488
491
|
this.$parent.$emit('filter-column', column, event);
|
|
489
492
|
}
|
|
@@ -610,16 +613,16 @@ export default {
|
|
|
610
613
|
* @param {Object} column - 列配置
|
|
611
614
|
* @returns {VNode|null} 渲染结果
|
|
612
615
|
*/
|
|
613
|
-
|
|
614
|
-
if (!column.
|
|
616
|
+
_renderfilterColumn(h, column) {
|
|
617
|
+
if (!column.filterColumn) return null;
|
|
615
618
|
|
|
616
619
|
return (
|
|
617
620
|
<span
|
|
618
621
|
class="filter-column"
|
|
619
|
-
on-click={($event) => this.
|
|
622
|
+
on-click={($event) => this.handlefilterColumnumn($event, column)}
|
|
620
623
|
>
|
|
621
624
|
<i
|
|
622
|
-
class={[typeof column.
|
|
625
|
+
class={[typeof column.filterColumn === 'string' ? column.filterColumn : 'es-icon-yingyong', 'filter-icon']}
|
|
623
626
|
></i>
|
|
624
627
|
</span>
|
|
625
628
|
);
|