xt-element-ui 2.0.3 → 2.0.4

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "xt-element-ui",
3
- "version": "2.0.3",
3
+ "version": "2.0.4",
4
4
  "description": "基于 Vue 2.7 + ElementUI 的企业级组件库,提供丰富的自定义组件和扩展组件",
5
5
  "main": "lib/index.common.js",
6
6
  "module": "lib/index.esm.js",
@@ -18,6 +18,7 @@
18
18
  },
19
19
  "devDependencies": {
20
20
  "@vue/cli-service": "~4.5.19",
21
+ "sass": "^1.56.0",
21
22
  "sass-loader": "^10.5.2",
22
23
  "vue": "^2.6.10",
23
24
  "vuepress": "^1.9.10",
@@ -35,7 +36,6 @@
35
36
  "dependencies": {
36
37
  "echarts": "^6.1.0",
37
38
  "element-ui": "^2.15.14",
38
- "sass": "^1.32.13",
39
39
  "vue-server-renderer": "^2.7.14",
40
40
  "xt-element-ui": "^2.0.2"
41
41
  },
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <div ref="barchart" class="bar-box"></div>
2
+ <div ref="barchart" class="bar-box" :style="chartStyle"></div>
3
3
  </template>
4
4
  <script>
5
5
  import EchartsUtil from "./utils";
@@ -28,6 +28,18 @@ export default {
28
28
  type: String,
29
29
  default: "medium"
30
30
  },
31
+ width: {
32
+ type: String,
33
+ default: "100%"
34
+ },
35
+ height: {
36
+ type: String,
37
+ default: "100%"
38
+ },
39
+ ratio: {
40
+ type: Number,
41
+ default: null
42
+ },
31
43
  fieldKeys: {
32
44
  type: Object,
33
45
  default: () => ({ label: "label", value: "value", data: "data" })
@@ -75,6 +87,18 @@ export default {
75
87
  name: "数量"
76
88
  };
77
89
  },
90
+ computed: {
91
+ chartStyle() {
92
+ const style = {};
93
+ if (this.width) style.width = this.width;
94
+ if (this.ratio) {
95
+ style.aspectRatio = this.ratio;
96
+ } else if (this.height) {
97
+ style.height = this.height;
98
+ }
99
+ return style;
100
+ }
101
+ },
78
102
  watch: {
79
103
  chartData: {
80
104
  deep: true,
@@ -96,6 +120,13 @@ export default {
96
120
  },
97
121
  mounted() {
98
122
  this.initChart();
123
+ EchartsUtil.bindResizeObserver(this.$refs.barchart, this.myChart);
124
+ },
125
+ beforeUnmount() {
126
+ EchartsUtil.unbindResizeObserver(this.$refs.barchart);
127
+ if (this.myChart) {
128
+ this.myChart.dispose();
129
+ }
99
130
  },
100
131
  methods: {
101
132
  initChart() {
@@ -171,12 +202,6 @@ export default {
171
202
  series: {
172
203
  name: _self.unit,
173
204
  type: "bar",
174
- markPoint: {
175
- data: [
176
- { type: "min", name: "Min" },
177
- { type: "max", name: "Max" }
178
- ]
179
- },
180
205
  avoidLabelOverlap: true,
181
206
  data: _self.chartData.map((item, ind) => {
182
207
  const label = item[keys.label];
@@ -192,9 +217,6 @@ export default {
192
217
  },
193
218
  dataZoom: _self.showZoom ? [{ height: 20, bottom: 0 }] : [],
194
219
  };
195
- if (!this.markPoint) {
196
- this.$delete(option.series[0], "markPoint");
197
- }
198
220
  if (this.simpleMode) {
199
221
  EchartsUtil.applySimpleMode(option, "bar");
200
222
  }
@@ -208,5 +230,6 @@ export default {
208
230
  position: relative;
209
231
  height: 100%;
210
232
  width: 100%;
233
+ min-height: 100px;
211
234
  }
212
235
  </style>
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <div ref="linechart" class="line-box"></div>
2
+ <div ref="linechart" class="line-box" :style="chartStyle"></div>
3
3
  </template>
4
4
  <script>
5
5
  import EchartsUtil from "./utils";
@@ -11,6 +11,18 @@ export default {
11
11
  type: String,
12
12
  default: "medium"
13
13
  },
14
+ width: {
15
+ type: String,
16
+ default: "100%"
17
+ },
18
+ height: {
19
+ type: String,
20
+ default: "100%"
21
+ },
22
+ ratio: {
23
+ type: Number,
24
+ default: null
25
+ },
14
26
  chartData: {
15
27
  type: Array,
16
28
  default: () => {
@@ -47,6 +59,18 @@ export default {
47
59
  myChart: null
48
60
  };
49
61
  },
62
+ computed: {
63
+ chartStyle() {
64
+ const style = {};
65
+ if (this.width) style.width = this.width;
66
+ if (this.ratio) {
67
+ style.aspectRatio = this.ratio;
68
+ } else if (this.height) {
69
+ style.height = this.height;
70
+ }
71
+ return style;
72
+ }
73
+ },
50
74
  watch: {
51
75
  chartData: {
52
76
  deep: true,
@@ -68,6 +92,13 @@ export default {
68
92
  },
69
93
  mounted() {
70
94
  this.initChart();
95
+ EchartsUtil.bindResizeObserver(this.$refs.linechart, this.myChart);
96
+ },
97
+ beforeUnmount() {
98
+ EchartsUtil.unbindResizeObserver(this.$refs.linechart);
99
+ if (this.myChart) {
100
+ this.myChart.dispose();
101
+ }
71
102
  },
72
103
  methods: {
73
104
  initChart() {
@@ -154,5 +185,6 @@ export default {
154
185
  position: relative;
155
186
  height: 100%;
156
187
  width: 100%;
188
+ min-height: 100px;
157
189
  }
158
190
  </style>
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <div ref="multilinechart" class="multiline-box"></div>
2
+ <div ref="multilinechart" class="multiline-box" :style="chartStyle"></div>
3
3
  </template>
4
4
  <script>
5
5
  import EchartsUtil from "./utils";
@@ -11,6 +11,18 @@ export default {
11
11
  type: String,
12
12
  default: "medium"
13
13
  },
14
+ width: {
15
+ type: String,
16
+ default: "100%"
17
+ },
18
+ height: {
19
+ type: String,
20
+ default: "100%"
21
+ },
22
+ ratio: {
23
+ type: Number,
24
+ default: null
25
+ },
14
26
  fieldKeys: {
15
27
  type: Object,
16
28
  default: () => ({ label: "label", value: "value", data: "data" })
@@ -102,6 +114,18 @@ export default {
102
114
  myChart: null
103
115
  };
104
116
  },
117
+ computed: {
118
+ chartStyle() {
119
+ const style = {};
120
+ if (this.width) style.width = this.width;
121
+ if (this.ratio) {
122
+ style.aspectRatio = this.ratio;
123
+ } else if (this.height) {
124
+ style.height = this.height;
125
+ }
126
+ return style;
127
+ }
128
+ },
105
129
  watch: {
106
130
  chartData: {
107
131
  deep: true,
@@ -110,16 +134,25 @@ export default {
110
134
  this.myChart && this.myChart.dispose();
111
135
  this.myChart = null;
112
136
  _self.initChart();
137
+ EchartsUtil.bindResizeObserver(this.$refs.multilinechart, this.myChart);
113
138
  }
114
139
  },
115
140
  theme(newVal) {
116
141
  this.myChart && this.myChart.dispose();
117
142
  this.myChart = null;
118
143
  this.initChart();
144
+ EchartsUtil.bindResizeObserver(this.$refs.multilinechart, this.myChart);
119
145
  }
120
146
  },
121
147
  mounted() {
122
148
  this.initChart();
149
+ EchartsUtil.bindResizeObserver(this.$refs.multilinechart, this.myChart);
150
+ },
151
+ beforeUnmount() {
152
+ EchartsUtil.unbindResizeObserver(this.$refs.multilinechart);
153
+ if (this.myChart) {
154
+ this.myChart.dispose();
155
+ }
123
156
  },
124
157
  methods: {
125
158
  initChart() {
@@ -248,5 +281,6 @@ export default {
248
281
  .multiline-box{
249
282
  height: 100%;
250
283
  width: 100%;
284
+ min-height: 100px;
251
285
  }
252
286
  </style>
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <div ref="piechart" class="pie-box"></div>
2
+ <div ref="piechart" class="pie-box" :style="chartStyle"></div>
3
3
  </template>
4
4
  <script>
5
5
  import EchartsUtil from "./utils";
@@ -11,6 +11,18 @@ export default {
11
11
  type: String,
12
12
  default: "medium"
13
13
  },
14
+ width: {
15
+ type: String,
16
+ default: "100%"
17
+ },
18
+ height: {
19
+ type: String,
20
+ default: "100%"
21
+ },
22
+ ratio: {
23
+ type: Number,
24
+ default: null
25
+ },
14
26
  chartData: {
15
27
  type: Array,
16
28
  default: () => {
@@ -61,6 +73,16 @@ export default {
61
73
  };
62
74
  },
63
75
  computed: {
76
+ chartStyle() {
77
+ const style = {};
78
+ if (this.width) style.width = this.width;
79
+ if (this.ratio) {
80
+ style.aspectRatio = this.ratio;
81
+ } else if (this.height) {
82
+ style.height = this.height;
83
+ }
84
+ return style;
85
+ },
64
86
  totalNum() {
65
87
  const keys = Object.assign(
66
88
  { label: "label", value: "value", data: "data" },
@@ -84,8 +106,15 @@ export default {
84
106
  mounted() {
85
107
  this.$nextTick(() => {
86
108
  this.initChart();
109
+ EchartsUtil.bindResizeObserver(this.$refs.piechart, this.myChart);
87
110
  });
88
111
  },
112
+ beforeUnmount() {
113
+ EchartsUtil.unbindResizeObserver(this.$refs.piechart);
114
+ if (this.myChart) {
115
+ this.myChart.dispose();
116
+ }
117
+ },
89
118
  methods: {
90
119
  initChart() {
91
120
  const _self = this;
@@ -163,5 +192,6 @@ export default {
163
192
  position: relative;
164
193
  height: 100%;
165
194
  width: 100%;
195
+ min-height: 100px;
166
196
  }
167
197
  </style>
@@ -63,7 +63,6 @@ export default {
63
63
  height: 100%;
64
64
  width: 100%;
65
65
  position: relative;
66
- @include font_color("fontColor");
67
66
  }
68
67
  .left{
69
68
  flex: 1;
@@ -114,6 +114,7 @@ EchartsUtil.EchartsUtil = {
114
114
  };
115
115
 
116
116
  EchartsUtil.chartInstanceList = [];
117
+ EchartsUtil.resizeObserverList = [];
117
118
 
118
119
  // === 极简模式(simpleMode)预设配置 ===
119
120
  // 极简模式:隐藏图例、隐藏坐标轴/网格线、缩小内边距、简化 tooltip、去除动画装饰
@@ -417,6 +418,30 @@ EchartsUtil.bindResize = function(chartIns) {
417
418
  chartIns._resizeLocked = true;
418
419
  };
419
420
 
421
+ EchartsUtil.bindResizeObserver = function(dom, chartIns) {
422
+ if (!dom || !chartIns || typeof ResizeObserver === 'undefined') return;
423
+
424
+ const observer = new ResizeObserver(() => {
425
+ chartIns.resize();
426
+ });
427
+
428
+ observer.observe(dom);
429
+
430
+ EchartsUtil.resizeObserverList.push({
431
+ dom,
432
+ observer,
433
+ chartIns
434
+ });
435
+ };
436
+
437
+ EchartsUtil.unbindResizeObserver = function(dom) {
438
+ const index = EchartsUtil.resizeObserverList.findIndex(item => item.dom === dom);
439
+ if (index !== -1) {
440
+ EchartsUtil.resizeObserverList[index].observer.disconnect();
441
+ EchartsUtil.resizeObserverList.splice(index, 1);
442
+ }
443
+ };
444
+
420
445
  EchartsUtil.destroy = function(chartIns) {
421
446
  if (chartIns) {
422
447
  chartIns.dispose();
@@ -435,6 +460,12 @@ EchartsUtil.destroyAll = function() {
435
460
  });
436
461
 
437
462
  this.chartInstanceList = [];
463
+
464
+ this.resizeObserverList.forEach(function(item) {
465
+ item.observer.disconnect();
466
+ });
467
+
468
+ this.resizeObserverList = [];
438
469
  };
439
470
 
440
471
  export default EchartsUtil;
@@ -1,15 +1,15 @@
1
1
  <template>
2
2
  <div style="display:inline-block">
3
- <FlexBox v-if="dateType=='quarter'" type="inline-flex" class="xt-date-picker" :class="{focus: isfocus}" :style="width?{width: `${width}px`}:{}">
3
+ <XtFlexBox v-if="dateType=='quarter'" type="inline-flex" class="xt-date-picker" :class="{focus: isfocus}" :style="width?{width: `${width}`}:{}">
4
4
  <Quarter v-model="timeStart" :format="format" placeholder="开始时间" quarter-type="quarter-start" clearable></Quarter>
5
5
  <span class="separator">{{ separator }}</span>
6
6
  <Quarter v-model="timeEnd" :format="format" placeholder="结束时间" quarter-type="quarter-end" clearable></Quarter>
7
- </FlexBox>
8
- <FlexBox v-else type="inline-flex" class="xt-date" :class="{focus: isfocus}" :style="width?{width: `${width}px`}:{}">
7
+ </XtFlexBox>
8
+ <XtFlexBox v-else type="inline-flex" class="xt-date" :class="{focus: isfocus}" :style="width?{width: `${width}px`}:{}">
9
9
  <el-date-picker ref="timeStart" key="startSelect" v-model="timeStart" size="small" :disabled="disabled" append-to-body :picker-options="startTimeRange" :format="format" :type="dateType" placeholder="开始时间" clearable @blur="$emit('blur')" @focus="$emit('focus')"></el-date-picker>
10
10
  <span class="separator">{{ separator }}</span>
11
11
  <el-date-picker ref="timeEnd" key="endSelect" v-model="timeEnd" size="small" :disabled="disabled" append-to-body :picker-options="endTimeRange" :format="format" :type="dateType" placeholder="结束时间" clearable @blur="$emit('blur')" @focus="$emit('focus')"></el-date-picker>
12
- </FlexBox>
12
+ </XtFlexBox>
13
13
  </div>
14
14
  </template>
15
15
  <script>
@@ -17,12 +17,12 @@ const typeFormatEnum = {
17
17
  datetime: "yyyy-MM-dd HH:mm", month: "yyyy-MM", year: "yyyy", date: "yyyy-MM-dd", quarter: "yyyy-Qq", week: "yyyy-WW"
18
18
  };
19
19
 
20
- import FlexBox from '../xt-flex-box/index.vue'
20
+ import XtFlexBox from '../xt-flex-box/index.vue'
21
21
  import Quarter from "./quarter.vue";
22
22
  export default {
23
23
  name: "XtDatePicker",
24
24
  components: {
25
- FlexBox,
25
+ XtFlexBox,
26
26
  Quarter
27
27
  },
28
28
  model: {
@@ -49,8 +49,8 @@ export default {
49
49
  },
50
50
  placeholder: {},
51
51
  width: {
52
- type: Number,
53
- default: 280
52
+ type: [String],
53
+ default: '100%'
54
54
  }
55
55
  },
56
56
  data() {
@@ -26,7 +26,7 @@ export default {
26
26
  showAside: { type: Boolean, default: true },
27
27
  diffHeight: {
28
28
  type: Number,
29
- default: 60
29
+ default: 0
30
30
  },
31
31
  minHeight: {
32
32
  type: Number,
@@ -8,7 +8,7 @@
8
8
  <i class="el-icon-arrow-left"></i>
9
9
  </div>
10
10
 
11
- <div ref="scrollContainer" class="xt-scroll-arrow__content" @scroll="handleScroll">
11
+ <div ref="scrollContainer" class="xt-scroll-arrow__content" @scroll="handleScroll" @click="handleClick">
12
12
  <slot></slot>
13
13
  </div>
14
14
 
@@ -62,6 +62,14 @@ export default {
62
62
  width: {
63
63
  type: [String, Number],
64
64
  default: ''
65
+ },
66
+ appendMode: {
67
+ type: Boolean,
68
+ default: false
69
+ },
70
+ clickMode: {
71
+ type: Boolean,
72
+ default: false
65
73
  }
66
74
  },
67
75
  data() {
@@ -96,9 +104,11 @@ export default {
96
104
  this.checkScroll()
97
105
  })
98
106
  this.addResizeObserver()
107
+ this.addMutationObserver()
99
108
  },
100
109
  beforeDestroy() {
101
110
  this.removeResizeObserver()
111
+ this.removeMutationObserver()
102
112
  },
103
113
  methods: {
104
114
  addResizeObserver() {
@@ -119,6 +129,30 @@ export default {
119
129
  this.resizeObserver.disconnect()
120
130
  }
121
131
  },
132
+ addMutationObserver() {
133
+ if (typeof MutationObserver !== 'undefined') {
134
+ this.mutationObserver = new MutationObserver(() => {
135
+ this.$nextTick(() => {
136
+ this.checkScroll()
137
+ if (this.appendMode) {
138
+ this.scrollToEnd()
139
+ }
140
+ })
141
+ })
142
+ const container = this.$refs.scrollContainer
143
+ if (container) {
144
+ this.mutationObserver.observe(container, {
145
+ childList: true,
146
+ subtree: true
147
+ })
148
+ }
149
+ }
150
+ },
151
+ removeMutationObserver() {
152
+ if (this.mutationObserver) {
153
+ this.mutationObserver.disconnect()
154
+ }
155
+ },
122
156
  checkScroll() {
123
157
  const container = this.$refs.scrollContainer
124
158
  if (!container) return
@@ -161,6 +195,34 @@ export default {
161
195
  this.checkScroll()
162
196
  this.$emit('scroll', this.$refs.scrollContainer)
163
197
  },
198
+ handleClick(e) {
199
+ if (!this.clickMode) return
200
+ const container = this.$refs.scrollContainer
201
+ if (!container) return
202
+
203
+ const target = e.target
204
+ if (!target || target === container) return
205
+
206
+ const containerRect = container.getBoundingClientRect()
207
+ const targetRect = target.getBoundingClientRect()
208
+
209
+ const isVisible = (
210
+ targetRect.left >= containerRect.left &&
211
+ targetRect.right <= containerRect.right &&
212
+ targetRect.top >= containerRect.top &&
213
+ targetRect.bottom <= containerRect.bottom
214
+ )
215
+
216
+ if (!isVisible) {
217
+ if (this.direction === 'horizontal') {
218
+ const scrollLeft = target.offsetLeft - (container.clientWidth - targetRect.width) / 2
219
+ container.scrollTo({ left: scrollLeft, behavior: 'smooth' })
220
+ } else {
221
+ const scrollTop = target.offsetTop - (container.clientHeight - targetRect.height) / 2
222
+ container.scrollTo({ top: scrollTop, behavior: 'smooth' })
223
+ }
224
+ }
225
+ },
164
226
  scrollLeft() {
165
227
  const container = this.$refs.scrollContainer
166
228
  if (container) {
@@ -184,6 +246,15 @@ export default {
184
246
  if (container) {
185
247
  container.scrollBy({ top: this.scrollStep, behavior: 'smooth' })
186
248
  }
249
+ },
250
+ scrollToEnd() {
251
+ const container = this.$refs.scrollContainer
252
+ if (!container) return
253
+ if (this.direction === 'horizontal') {
254
+ container.scrollTo({ left: container.scrollWidth, behavior: 'smooth' })
255
+ } else {
256
+ container.scrollTo({ top: container.scrollHeight, behavior: 'smooth' })
257
+ }
187
258
  }
188
259
  }
189
260
  }
@@ -331,9 +331,6 @@ export default {
331
331
  }
332
332
  .el-input{
333
333
  &:hover:not(.is-disabled) {
334
- .el-input__inner{
335
- @include border_color("borderColor");
336
- }
337
334
  &.is-selected.isclearable{
338
335
  .el-input__icon{
339
336
  &.close{
@@ -349,9 +346,6 @@ export default {
349
346
  .el-input__icon-arrow-down{
350
347
  transition: rotate(-180deg);
351
348
  }
352
- .el-input__inner{
353
- @include border_color("$subMenuActiveText");
354
- }
355
349
  }
356
350
  }
357
351
  }
@@ -380,7 +374,6 @@ export default {
380
374
  }
381
375
  .el-tree--highlight-current .el-tree-node.is-current > .el-tree-node__content{
382
376
  color: #409EFF;
383
- @include font_color("primaryColor");
384
377
  font-weight: bold;
385
378
  }
386
379
  </style>
@@ -33,6 +33,7 @@
33
33
  :right-bracket="rightBracket"
34
34
  :field-keys="fieldKeys"
35
35
  :disabled="disabled"
36
+ :allow-negative="allowNegative"
36
37
  @input="(val) => onItemInput(val, idx)"
37
38
  @max-change="onMaxChange"
38
39
  @min-change="onMinChange"
@@ -100,6 +101,7 @@ export default {
100
101
  // 阶梯增量:新增/校正时,下一条阶梯的 min = 当前 max = 当前 min + step(默认 1)
101
102
  step: { type: Number, default: 10 },
102
103
  disabled: { type: Boolean, default: false },
104
+ allowNegative: { type: Boolean, default: false },
103
105
  tip: {
104
106
  type: String,
105
107
  default: '区间左闭右闭 [min, max],最后一级为 [min, +∞),保证连续且不重叠。'
@@ -217,7 +219,7 @@ export default {
217
219
  message: `第${i + 1}${this.stepName}价格不能为空`,
218
220
  type: 'error'
219
221
  })
220
- } else if (price < 0) {
222
+ } else if (price < 0 && !this.allowNegative) {
221
223
  errors.push({
222
224
  field: `stepPrice[${i}].price`,
223
225
  message: `第${i + 1}${this.stepName}价格不能为负数`,
@@ -231,7 +233,7 @@ export default {
231
233
  message: `第${i + 1}${this.stepName}下限不能为空`,
232
234
  type: 'error'
233
235
  })
234
- } else if (min < 0) {
236
+ } else if (min < 0 && !this.allowNegative) {
235
237
  errors.push({
236
238
  field: `stepPrice[${i}].min`,
237
239
  message: `第${i + 1}${this.stepName}下限不能为负数`,
@@ -67,6 +67,7 @@ export default {
67
67
  itemsLength: { type: Number, default: 1 },
68
68
  removable: { type: Boolean, default: true },
69
69
  disabled: { type: Boolean, default: false },
70
+ allowNegative: { type: Boolean, default: false },
70
71
  minLocked: { type: Boolean, default: false },
71
72
  unit: { type: String, default: '元' },
72
73
  precision: { type: Number, default: 2 },
@@ -187,7 +188,7 @@ export default {
187
188
  return
188
189
  }
189
190
  let v = this.safeNumber(rawVal, 0)
190
- if (v < 0) v = 0
191
+ if (v < 0 && !this.allowNegative) v = 0
191
192
  v = Number(v.toFixed(this.precision))
192
193
  this.priceInput = v
193
194
  this.emitChange({ [this.keyPrice]: v })
@@ -37,8 +37,8 @@
37
37
  </template>
38
38
  <script>
39
39
  import ImageViewer from "./preview.vue";
40
- import { getToken } from "@/utils/auth";
41
40
  export default {
41
+ name: "XtUpload",
42
42
  components: {
43
43
  ImageViewer
44
44
  },
@@ -58,6 +58,10 @@ export default {
58
58
  default: "",
59
59
  required: true
60
60
  },
61
+ accessToken: {
62
+ type: String,
63
+ default: ""
64
+ },
61
65
  autoUpload: {
62
66
  type: Boolean,
63
67
  default: true
@@ -111,14 +115,7 @@ export default {
111
115
  },
112
116
  data() {
113
117
  return {
114
- accessToken: getToken(),
115
118
  YSSQP: this.baseUrl,
116
- // upload: {
117
- // data: { accessToken: getToken() },
118
- // limit: 5,
119
- // accept: ".jpg,.png,.pdf",
120
- // multiple: false
121
- // },
122
119
  previewVisible: false,
123
120
  uploading: false,
124
121
  imageUrl: "",