@liuzengwei/element-ui 2.15.5-xn.51 → 2.15.5-xn.53

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.
Files changed (76) hide show
  1. package/lib/alert.js +2 -2
  2. package/lib/area-picker.js +2 -2
  3. package/lib/aside.js +2 -2
  4. package/lib/backtop.js +2 -2
  5. package/lib/badge.js +2 -2
  6. package/lib/breadcrumb-item.js +2 -2
  7. package/lib/breadcrumb.js +2 -2
  8. package/lib/button-group.js +2 -2
  9. package/lib/button.js +2 -2
  10. package/lib/calendar.js +2 -2
  11. package/lib/card.js +2 -2
  12. package/lib/carousel-item.js +2 -2
  13. package/lib/carousel.js +2 -2
  14. package/lib/cascader-panel.js +2 -2
  15. package/lib/cascader.js +4 -4
  16. package/lib/checkbox-button.js +2 -2
  17. package/lib/checkbox-group.js +2 -2
  18. package/lib/checkbox.js +2 -2
  19. package/lib/collapse-item.js +2 -2
  20. package/lib/collapse.js +2 -2
  21. package/lib/color-picker.js +4 -4
  22. package/lib/container.js +2 -2
  23. package/lib/date-picker.js +5 -5
  24. package/lib/dialog.js +2 -2
  25. package/lib/divider.js +2 -2
  26. package/lib/drawer.js +573 -25
  27. package/lib/dropdown-item.js +2 -2
  28. package/lib/dropdown-menu.js +2 -2
  29. package/lib/element-ui.common.js +547 -20
  30. package/lib/footer.js +2 -2
  31. package/lib/form.js +2 -2
  32. package/lib/header.js +2 -2
  33. package/lib/icon.js +2 -2
  34. package/lib/image.js +2 -2
  35. package/lib/index.js +1 -1
  36. package/lib/input-number.js +2 -2
  37. package/lib/link.js +2 -2
  38. package/lib/loading.js +2 -2
  39. package/lib/main.js +2 -2
  40. package/lib/menu-item-group.js +2 -2
  41. package/lib/menu-item.js +2 -2
  42. package/lib/message-box.js +4 -4
  43. package/lib/message.js +2 -2
  44. package/lib/notification.js +2 -2
  45. package/lib/option-group.js +2 -2
  46. package/lib/page-header.js +2 -2
  47. package/lib/pagination.js +2 -2
  48. package/lib/popover.js +2 -2
  49. package/lib/progress.js +2 -2
  50. package/lib/radio-button.js +2 -2
  51. package/lib/radio-group.js +2 -2
  52. package/lib/radio.js +9 -9
  53. package/lib/rate.js +2 -2
  54. package/lib/select.js +2 -2
  55. package/lib/spinner.js +2 -2
  56. package/lib/step.js +2 -2
  57. package/lib/steps.js +2 -2
  58. package/lib/switch.js +2 -2
  59. package/lib/tab-pane.js +2 -2
  60. package/lib/table.js +4 -4
  61. package/lib/theme-chalk/drawer.css +1 -1
  62. package/lib/theme-chalk/index.css +1 -1
  63. package/lib/time-picker.js +5 -5
  64. package/lib/time-select.js +2 -2
  65. package/lib/timeline-item.js +2 -2
  66. package/lib/tooltip.js +2 -2
  67. package/lib/transfer.js +2 -2
  68. package/lib/trigger.js +5 -5
  69. package/lib/upload.js +8 -8
  70. package/package.json +1 -1
  71. package/packages/drawer/src/main.vue +321 -9
  72. package/packages/theme-chalk/lib/drawer.css +1 -1
  73. package/packages/theme-chalk/lib/index.css +1 -1
  74. package/packages/theme-chalk/src/drawer.scss +31 -0
  75. package/src/index.js +1 -1
  76. package/types/drawer.d.ts +16 -0
@@ -323,7 +323,7 @@ render._withStripped = true
323
323
  var date_util_ = __webpack_require__(1);
324
324
 
325
325
  // EXTERNAL MODULE: external "@liuzengwei/element-ui/lib/mixins/locale"
326
- var locale_ = __webpack_require__(6);
326
+ var locale_ = __webpack_require__(7);
327
327
  var locale_default = /*#__PURE__*/__webpack_require__.n(locale_);
328
328
 
329
329
  // EXTERNAL MODULE: ./packages/date-picker/src/basic/time-spinner.vue + 4 modules
@@ -784,7 +784,7 @@ render._withStripped = true
784
784
  // CONCATENATED MODULE: ./packages/date-picker/src/picker.vue?vue&type=template&id=79ae069f&
785
785
 
786
786
  // EXTERNAL MODULE: external "vue"
787
- var external_vue_ = __webpack_require__(7);
787
+ var external_vue_ = __webpack_require__(6);
788
788
  var external_vue_default = /*#__PURE__*/__webpack_require__.n(external_vue_);
789
789
 
790
790
  // EXTERNAL MODULE: external "@liuzengwei/element-ui/lib/utils/clickoutside"
@@ -2483,14 +2483,14 @@ module.exports = require("@liuzengwei/element-ui/lib/utils/vue-popper");
2483
2483
  /***/ 6:
2484
2484
  /***/ (function(module, exports) {
2485
2485
 
2486
- module.exports = require("@liuzengwei/element-ui/lib/mixins/locale");
2486
+ module.exports = require("vue");
2487
2487
 
2488
2488
  /***/ }),
2489
2489
 
2490
2490
  /***/ 7:
2491
2491
  /***/ (function(module, exports) {
2492
2492
 
2493
- module.exports = require("vue");
2493
+ module.exports = require("@liuzengwei/element-ui/lib/mixins/locale");
2494
2494
 
2495
2495
  /***/ }),
2496
2496
 
@@ -2646,7 +2646,7 @@ render._withStripped = true
2646
2646
  var date_util_ = __webpack_require__(1);
2647
2647
 
2648
2648
  // EXTERNAL MODULE: external "@liuzengwei/element-ui/lib/mixins/locale"
2649
- var locale_ = __webpack_require__(6);
2649
+ var locale_ = __webpack_require__(7);
2650
2650
  var locale_default = /*#__PURE__*/__webpack_require__.n(locale_);
2651
2651
 
2652
2652
  // EXTERNAL MODULE: ./packages/date-picker/src/basic/time-spinner.vue + 4 modules
@@ -410,7 +410,7 @@ render._withStripped = true
410
410
  // CONCATENATED MODULE: ./packages/date-picker/src/picker.vue?vue&type=template&id=79ae069f&
411
411
 
412
412
  // EXTERNAL MODULE: external "vue"
413
- var external_vue_ = __webpack_require__(7);
413
+ var external_vue_ = __webpack_require__(6);
414
414
  var external_vue_default = /*#__PURE__*/__webpack_require__.n(external_vue_);
415
415
 
416
416
  // EXTERNAL MODULE: external "@liuzengwei/element-ui/lib/utils/clickoutside"
@@ -1405,7 +1405,7 @@ module.exports = require("@liuzengwei/element-ui/lib/utils/vue-popper");
1405
1405
 
1406
1406
  /***/ }),
1407
1407
 
1408
- /***/ 7:
1408
+ /***/ 6:
1409
1409
  /***/ (function(module, exports) {
1410
1410
 
1411
1411
  module.exports = require("vue");
@@ -82,7 +82,7 @@ module.exports =
82
82
  /******/
83
83
  /******/
84
84
  /******/ // Load entry module and return exports
85
- /******/ return __webpack_require__(__webpack_require__.s = 132);
85
+ /******/ return __webpack_require__(__webpack_require__.s = 133);
86
86
  /******/ })
87
87
  /************************************************************************/
88
88
  /******/ ({
@@ -189,7 +189,7 @@ function normalizeComponent (
189
189
 
190
190
  /***/ }),
191
191
 
192
- /***/ 132:
192
+ /***/ 133:
193
193
  /***/ (function(module, __webpack_exports__, __webpack_require__) {
194
194
 
195
195
  "use strict";
package/lib/tooltip.js CHANGED
@@ -108,7 +108,7 @@ var dom_ = __webpack_require__(2);
108
108
  var util_ = __webpack_require__(3);
109
109
 
110
110
  // EXTERNAL MODULE: external "vue"
111
- var external_vue_ = __webpack_require__(7);
111
+ var external_vue_ = __webpack_require__(6);
112
112
  var external_vue_default = /*#__PURE__*/__webpack_require__.n(external_vue_);
113
113
 
114
114
  // CONCATENATED MODULE: ./packages/tooltip/src/main.js
@@ -414,7 +414,7 @@ module.exports = require("@liuzengwei/element-ui/lib/utils/vue-popper");
414
414
 
415
415
  /***/ }),
416
416
 
417
- /***/ 7:
417
+ /***/ 6:
418
418
  /***/ (function(module, exports) {
419
419
 
420
420
  module.exports = require("vue");
package/lib/transfer.js CHANGED
@@ -231,7 +231,7 @@ module.exports = require("@liuzengwei/element-ui/lib/checkbox-group");
231
231
 
232
232
  /***/ }),
233
233
 
234
- /***/ 6:
234
+ /***/ 7:
235
235
  /***/ (function(module, exports) {
236
236
 
237
237
  module.exports = require("@liuzengwei/element-ui/lib/mixins/locale");
@@ -369,7 +369,7 @@ var emitter_ = __webpack_require__(4);
369
369
  var emitter_default = /*#__PURE__*/__webpack_require__.n(emitter_);
370
370
 
371
371
  // EXTERNAL MODULE: external "@liuzengwei/element-ui/lib/mixins/locale"
372
- var locale_ = __webpack_require__(6);
372
+ var locale_ = __webpack_require__(7);
373
373
  var locale_default = /*#__PURE__*/__webpack_require__.n(locale_);
374
374
 
375
375
  // CONCATENATED MODULE: ./node_modules/vue-loader/lib/loaders/templateLoader.js??vue-loader-options!./node_modules/vue-loader/lib??vue-loader-options!./packages/transfer/src/transfer-panel.vue?vue&type=template&id=2ddab8bd&
package/lib/trigger.js CHANGED
@@ -275,7 +275,7 @@ var vue_popper_default = /*#__PURE__*/__webpack_require__.n(vue_popper_);
275
275
  var dom_ = __webpack_require__(2);
276
276
 
277
277
  // EXTERNAL MODULE: external "vue"
278
- var external_vue_ = __webpack_require__(7);
278
+ var external_vue_ = __webpack_require__(6);
279
279
  var external_vue_default = /*#__PURE__*/__webpack_require__.n(external_vue_);
280
280
 
281
281
  // CONCATENATED MODULE: ./node_modules/babel-loader/lib!./node_modules/vue-loader/lib??vue-loader-options!./packages/trigger/src/main.vue?vue&type=script&lang=js&
@@ -907,17 +907,17 @@ module.exports = require("@liuzengwei/element-ui/lib/utils/vue-popper");
907
907
 
908
908
  /***/ }),
909
909
 
910
- /***/ 64:
910
+ /***/ 6:
911
911
  /***/ (function(module, exports) {
912
912
 
913
- module.exports = require("@liuzengwei/element-ui/lib/utils/popper");
913
+ module.exports = require("vue");
914
914
 
915
915
  /***/ }),
916
916
 
917
- /***/ 7:
917
+ /***/ 64:
918
918
  /***/ (function(module, exports) {
919
919
 
920
- module.exports = require("vue");
920
+ module.exports = require("@liuzengwei/element-ui/lib/utils/popper");
921
921
 
922
922
  /***/ })
923
923
 
package/lib/upload.js CHANGED
@@ -210,13 +210,6 @@ module.exports = require("@liuzengwei/element-ui/lib/progress");
210
210
 
211
211
  /***/ }),
212
212
 
213
- /***/ 6:
214
- /***/ (function(module, exports) {
215
-
216
- module.exports = require("@liuzengwei/element-ui/lib/mixins/locale");
217
-
218
- /***/ }),
219
-
220
213
  /***/ 69:
221
214
  /***/ (function(module, __webpack_exports__, __webpack_require__) {
222
215
 
@@ -387,7 +380,7 @@ upload_listvue_type_template_id_173fedf5_render._withStripped = true
387
380
  // CONCATENATED MODULE: ./packages/upload/src/upload-list.vue?vue&type=template&id=173fedf5&
388
381
 
389
382
  // EXTERNAL MODULE: external "@liuzengwei/element-ui/lib/mixins/locale"
390
- var locale_ = __webpack_require__(6);
383
+ var locale_ = __webpack_require__(7);
391
384
  var locale_default = /*#__PURE__*/__webpack_require__.n(locale_);
392
385
 
393
386
  // EXTERNAL MODULE: external "@liuzengwei/element-ui/lib/progress"
@@ -1393,6 +1386,13 @@ src.install = function (Vue) {
1393
1386
 
1394
1387
  /* harmony default export */ var packages_upload = __webpack_exports__["default"] = (src);
1395
1388
 
1389
+ /***/ }),
1390
+
1391
+ /***/ 7:
1392
+ /***/ (function(module, exports) {
1393
+
1394
+ module.exports = require("@liuzengwei/element-ui/lib/mixins/locale");
1395
+
1396
1396
  /***/ })
1397
1397
 
1398
1398
  /******/ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@liuzengwei/element-ui",
3
- "version": "2.15.5-xn.51",
3
+ "version": "2.15.5-xn.53",
4
4
  "description": "A Component Library for Vue.js (Fork of Element UI).",
5
5
  "main": "lib/element-ui.common.js",
6
6
  "files": [
@@ -4,12 +4,13 @@
4
4
  @after-enter="afterEnter"
5
5
  @after-leave="afterLeave">
6
6
  <div
7
- class="el-drawer__wrapper"
7
+ :class="referenceMode ? 'el-drawer__wrapper-reference' : 'el-drawer__wrapper'"
8
+ :style="wrapperStyle"
8
9
  tabindex="-1"
9
10
  v-show="visible">
10
11
  <div
11
12
  class="el-drawer__container"
12
- :class="visible && 'el-drawer__open'"
13
+ :class="[visible && 'el-drawer__open', referenceMode && 'el-drawer__reference-mode']"
13
14
  @click.self="handleWrapperClick"
14
15
  role="document"
15
16
  tabindex="-1">
@@ -18,8 +19,8 @@
18
19
  aria-labelledby="el-drawer__title"
19
20
  :aria-label="title"
20
21
  class="el-drawer"
21
- :class="[direction, customClass]"
22
- :style="isHorizontal ? `width: ${drawerSize}` : `height: ${drawerSize}`"
22
+ :class="[effectiveDirection, customClass, referenceMode && 'is-reference']"
23
+ :style="drawerStyle"
23
24
  ref="drawer"
24
25
  role="dialog"
25
26
  tabindex="-1"
@@ -48,6 +49,8 @@
48
49
 
49
50
  <script>
50
51
  import Popup from 'element-ui/src/utils/popup';
52
+ import PopupManager from 'element-ui/src/utils/popup/popup-manager';
53
+ import { getStyle } from 'element-ui/src/utils/dom';
51
54
  import emitter from 'element-ui/src/mixins/emitter';
52
55
 
53
56
  export default {
@@ -110,6 +113,21 @@ export default {
110
113
  withHeader: {
111
114
  type: Boolean,
112
115
  default: true
116
+ },
117
+ reference: {
118
+ type: [String, Object, typeof window !== 'undefined' ? window.HTMLElement : Object],
119
+ default: null
120
+ },
121
+ placement: {
122
+ type: String,
123
+ default: 'right',
124
+ validator(val) {
125
+ return ['top', 'bottom', 'left', 'right'].indexOf(val) !== -1;
126
+ }
127
+ },
128
+ offset: {
129
+ type: Number,
130
+ default: 0
113
131
  }
114
132
  },
115
133
  computed: {
@@ -118,12 +136,51 @@ export default {
118
136
  },
119
137
  drawerSize() {
120
138
  return typeof this.size === 'number' ? `${this.size}px` : this.size;
139
+ },
140
+ referenceMode() {
141
+ return !!this.reference;
142
+ },
143
+ effectiveDirection() {
144
+ // 在 reference 模式下,根据 placement 映射到对应的 direction
145
+ if (this.referenceMode) {
146
+ const placementToDirection = {
147
+ 'top': 'btt',
148
+ 'bottom': 'ttb',
149
+ 'left': 'ltr',
150
+ 'right': 'rtl'
151
+ };
152
+ return placementToDirection[this.placement] || 'rtl';
153
+ }
154
+ return this.direction;
155
+ },
156
+ wrapperStyle() {
157
+ // 在 reference 模式下,将 z-index 设置在 wrapper 上,与全局模式保持一致
158
+ if (this.referenceMode && this.drawerZIndex) {
159
+ return { zIndex: this.drawerZIndex };
160
+ }
161
+ return null;
162
+ },
163
+ drawerStyle() {
164
+ if (this.referenceMode) {
165
+ const style = { ...this.position };
166
+ if (this.placement === 'left' || this.placement === 'right') {
167
+ style.width = this.drawerSize;
168
+ } else {
169
+ style.height = this.drawerSize;
170
+ }
171
+ return style;
172
+ } else {
173
+ return this.isHorizontal ? `width: ${this.drawerSize}` : `height: ${this.drawerSize}`;
174
+ }
121
175
  }
122
176
  },
123
177
  data() {
124
178
  return {
125
179
  closed: false,
126
- prevActiveElement: null
180
+ prevActiveElement: null,
181
+ position: {},
182
+ drawerZIndex: null,
183
+ modalZIndex: null
127
184
  };
128
185
  },
129
186
  watch: {
@@ -131,7 +188,34 @@ export default {
131
188
  if (val) {
132
189
  this.closed = false;
133
190
  this.$emit('open');
134
- if (this.appendToBody) {
191
+ if (this.referenceMode) {
192
+ // z-index 已经通过 drawerStyle computed 属性设置
193
+ const referenceEl = this.getReferenceElement();
194
+ if (referenceEl) {
195
+ referenceEl.appendChild(this.$el);
196
+ }
197
+ // 在 drawer 挂载后创建 modal
198
+ this.$nextTick(() => {
199
+ // drawer 的 z-index 已经在 appendChild 前设置
200
+
201
+ // 创建/显示 modal(使用预分配的较低值)
202
+ if (this.modal) {
203
+ this.createReferenceModal({
204
+ modalClass: this.modalClass,
205
+ modalFade: this.modalFade
206
+ });
207
+ }
208
+
209
+ // 更新位置
210
+ this.updatePosition();
211
+
212
+ // 清理可能被 PopupManager 创建的全局 modal
213
+ // 延迟执行,确保全局 modal 已经被创建后再移除
214
+ setTimeout(() => {
215
+ this.removeGlobalModal();
216
+ }, 300);
217
+ });
218
+ } else if (this.appendToBody) {
135
219
  document.body.appendChild(this.$el);
136
220
  }
137
221
  this.prevActiveElement = document.activeElement;
@@ -142,6 +226,10 @@ export default {
142
226
  this.rendered = false;
143
227
  }
144
228
  }
229
+ // 关闭 reference 模式的 modal
230
+ if (this.referenceMode) {
231
+ this.closeReferenceModal();
232
+ }
145
233
  this.$nextTick(() => {
146
234
  if (this.prevActiveElement) {
147
235
  this.prevActiveElement.focus();
@@ -151,6 +239,118 @@ export default {
151
239
  }
152
240
  },
153
241
  methods: {
242
+ doOpen(props) {
243
+ // 在 reference 模式下,需要让遮罩层挂载到参考元素而不是 body
244
+ if (this.referenceMode) {
245
+ // 手动实现 doOpen 的逻辑,但将 modal 挂载到 reference 元素
246
+ if (this.$isServer) return;
247
+ if (this.willOpen && !this.willOpen()) return;
248
+ if (this.opened) return;
249
+
250
+ this._opening = true;
251
+
252
+ const dom = this.$el;
253
+ const zIndex = props.zIndex;
254
+
255
+ if (zIndex) {
256
+ PopupManager.zIndex = zIndex;
257
+ }
258
+
259
+ // modal 的创建已经移到 watch visible 中,在 drawer 挂载后执行
260
+ // 这里预先分配 z-index,确保 modal 和 drawer 的层级关系正确
261
+ // 每次打开都重新分配,避免复用时的 z-index 错乱
262
+ this.modalZIndex = PopupManager.nextZIndex();
263
+ this.drawerZIndex = PopupManager.nextZIndex();
264
+
265
+ if (getStyle(dom, 'position') === 'static') {
266
+ dom.style.position = 'absolute';
267
+ }
268
+
269
+ // z-index 的设置已经移到 watch visible 中,在 modal 创建后设置
270
+ this.opened = true;
271
+
272
+ this.onOpen && this.onOpen();
273
+
274
+ this.doAfterOpen();
275
+ } else {
276
+ // 非 reference 模式,使用原始的 doOpen
277
+ this.$options.mixins[0].methods.doOpen.call(this, props);
278
+ }
279
+ },
280
+ createReferenceModal(props) {
281
+ // 创建并挂载 modal 到 reference 元素
282
+ const referenceEl = this.getReferenceElement();
283
+ if (!referenceEl) return;
284
+
285
+ // 创建或复用 modal DOM
286
+ let modalDom = this._referenceModalDom;
287
+ if (!modalDom) {
288
+ modalDom = document.createElement('div');
289
+ modalDom.className = 'v-modal';
290
+ modalDom.tabIndex = 0;
291
+
292
+ // 使用预先分配的 modal z-index,确保 drawer 已经有更高的 z-index
293
+ const modalZIndex = this.modalZIndex || PopupManager.nextZIndex();
294
+ modalDom.style.zIndex = modalZIndex;
295
+
296
+ // 关键:在 reference 模式下使用 absolute 定位,而不是 fixed
297
+ modalDom.style.position = 'absolute';
298
+ modalDom.style.left = '0';
299
+ modalDom.style.top = '0';
300
+ modalDom.style.width = '100%';
301
+ modalDom.style.height = '100%';
302
+
303
+ if (props.modalClass) {
304
+ const classArr = props.modalClass.trim().split(/\s+/);
305
+ classArr.forEach(cls => modalDom.classList.add(cls));
306
+ }
307
+
308
+ // 添加淡入动画
309
+ if (props.modalFade) {
310
+ modalDom.classList.add('v-modal-enter');
311
+ setTimeout(() => {
312
+ modalDom.classList.remove('v-modal-enter');
313
+ }, 200);
314
+ }
315
+
316
+ // 直接挂载到 reference 元素内部
317
+ referenceEl.appendChild(modalDom);
318
+
319
+ // 点击 modal 时的处理
320
+ modalDom.addEventListener('click', () => {
321
+ if (this.closeOnClickModal) {
322
+ this.closeDrawer();
323
+ }
324
+ });
325
+
326
+ // 保存引用以便后续清理
327
+ this._referenceModalDom = modalDom;
328
+ } else {
329
+ // 复用 modal 时,使用预分配的 z-index
330
+ modalDom.style.display = '';
331
+ modalDom.style.zIndex = this.modalZIndex || PopupManager.nextZIndex();
332
+ }
333
+ },
334
+ closeReferenceModal() {
335
+ // 关闭 reference 模式的 modal
336
+ if (this._referenceModalDom) {
337
+ this._referenceModalDom.style.display = 'none';
338
+ }
339
+ },
340
+ removeGlobalModal() {
341
+ // 移除 PopupManager 可能创建的全局 modal(在 body 下的)
342
+ // 只在 reference 模式下调用此方法
343
+ if (this.referenceMode) {
344
+ // 查找并移除 body 下与此 drawer 关联的 modal
345
+ const globalModals = document.body.querySelectorAll('.v-modal');
346
+ globalModals.forEach(modal => {
347
+ // 移除 body 下的所有 modal(它们不应该存在)
348
+ if (modal.parentNode === document.body) {
349
+ document.body.removeChild(modal);
350
+ }
351
+ });
352
+ }
353
+ },
154
354
  afterEnter() {
155
355
  this.$emit('opened');
156
356
  },
@@ -184,22 +384,134 @@ export default {
184
384
  // pressing `ESC` will call this method, and also close the drawer.
185
385
  // This method also calls `beforeClose` if there was one.
186
386
  this.closeDrawer();
387
+ },
388
+ getReferenceElement() {
389
+ if (typeof this.reference === 'string') {
390
+ return document.querySelector(this.reference);
391
+ } else if (this.reference && this.reference.$el) {
392
+ return this.reference.$el;
393
+ } else {
394
+ return this.reference;
395
+ }
396
+ },
397
+ updatePosition() {
398
+ if (!this.referenceMode) return;
399
+
400
+ const referenceEl = this.getReferenceElement();
401
+ if (!referenceEl) {
402
+ console.warn('[ElDrawer] Reference element not found');
403
+ return;
404
+ }
405
+
406
+ // 确保参考元素有 position 样式
407
+ const computedStyle = window.getComputedStyle(referenceEl);
408
+ if (computedStyle.position === 'static') {
409
+ referenceEl.style.position = 'relative';
410
+ }
411
+
412
+ const { placement, offset } = this;
413
+ const position = {};
414
+
415
+ switch (placement) {
416
+ case 'top':
417
+ position.left = '0';
418
+ position.bottom = `${offset}px`;
419
+ position.top = 'auto';
420
+ position.right = '0';
421
+ break;
422
+ case 'bottom':
423
+ position.left = '0';
424
+ position.top = `${offset}px`;
425
+ position.bottom = 'auto';
426
+ position.right = '0';
427
+ break;
428
+ case 'left':
429
+ position.top = '0';
430
+ position.right = 'auto';
431
+ position.left = `${offset}px`;
432
+ position.bottom = '0';
433
+ break;
434
+ case 'right':
435
+ position.top = '0';
436
+ position.left = 'auto';
437
+ position.right = `${offset}px`;
438
+ position.bottom = '0';
439
+ break;
440
+ }
441
+
442
+ this.position = position;
443
+ },
444
+ handleScroll() {
445
+ if (this.referenceMode && this.visible) {
446
+ this.updatePosition();
447
+ }
448
+ },
449
+ handleResize() {
450
+ if (this.referenceMode && this.visible) {
451
+ this.updatePosition();
452
+ }
453
+ }
454
+ },
455
+ beforeMount() {
456
+ // 在 reference 模式下,我们不使用 PopupManager 的 modal
457
+ // 设置一个内部标志来阻止 PopupManager 创建 modal
458
+ if (this.referenceMode) {
459
+ // 保存原始的 modal 属性
460
+ this._originalModal = this.modal;
461
+ // 临时将 modal 设为 false,这样 Popup mixin 的逻辑不会调用 PopupManager.openModal
462
+ // 注意:这个技巧可能不work,因为 modal 是 prop
187
463
  }
188
464
  },
189
465
  mounted() {
190
466
  if (this.visible) {
191
467
  this.rendered = true;
192
468
  this.open();
193
- if (this.appendToBody) {
469
+ if (this.referenceMode) {
470
+ const referenceEl = this.getReferenceElement();
471
+ if (referenceEl) {
472
+ referenceEl.appendChild(this.$el);
473
+ }
474
+ } else if (this.appendToBody) {
194
475
  document.body.appendChild(this.$el);
195
476
  }
196
477
  }
197
- },
198
- destroyed() {
478
+ if (this.referenceMode) {
479
+ window.addEventListener('scroll', this.handleScroll, true);
480
+ window.addEventListener('resize', this.handleResize);
481
+ }
482
+ }, beforeDestroy() {
483
+ // 在 reference 模式下,不使用 PopupManager 管理 modal
484
+ // 所以需要阻止 Popup mixin 的 beforeDestroy 调用 PopupManager.closeModal
485
+ if (!this.referenceMode) {
486
+ // 非 reference 模式,调用 mixin 的 beforeDestroy
487
+ if (this.$options.mixins && this.$options.mixins[0].beforeDestroy) {
488
+ this.$options.mixins[0].beforeDestroy.call(this);
489
+ }
490
+ } else {
491
+ // reference 模式,只执行必要的清理
492
+ if (this._popupId) {
493
+ PopupManager.deregister(this._popupId);
494
+ // 不调用 PopupManager.closeModal,因为我们用的是自定义 modal
495
+ }
496
+ this.restoreBodyStyle();
497
+ }
498
+ }, destroyed() {
199
499
  // if appendToBody is true, remove DOM node after destroy
200
500
  if (this.appendToBody && this.$el && this.$el.parentNode) {
201
501
  this.$el.parentNode.removeChild(this.$el);
202
502
  }
503
+ if (this.referenceMode && this.$el && this.$el.parentNode) {
504
+ this.$el.parentNode.removeChild(this.$el);
505
+ }
506
+ // 清理 reference modal
507
+ if (this.referenceMode && this._referenceModalDom && this._referenceModalDom.parentNode) {
508
+ this._referenceModalDom.parentNode.removeChild(this._referenceModalDom);
509
+ this._referenceModalDom = null;
510
+ }
511
+ if (this.referenceMode) {
512
+ window.removeEventListener('scroll', this.handleScroll, true);
513
+ window.removeEventListener('resize', this.handleResize);
514
+ }
203
515
  }
204
516
  };
205
517
  </script>
@@ -1 +1 @@
1
- .el-drawer.btt,.el-drawer.ttb,.el-drawer__container{left:0;right:0;width:100%}@-webkit-keyframes el-drawer-fade-in{0%{opacity:0}100%{opacity:1}}@keyframes el-drawer-fade-in{0%{opacity:0}100%{opacity:1}}@-webkit-keyframes rtl-drawer-in{0%{-webkit-transform:translate(100%,0);transform:translate(100%,0)}100%{-webkit-transform:translate(0,0);transform:translate(0,0)}}@keyframes rtl-drawer-in{0%{-webkit-transform:translate(100%,0);transform:translate(100%,0)}100%{-webkit-transform:translate(0,0);transform:translate(0,0)}}@-webkit-keyframes rtl-drawer-out{0%{-webkit-transform:translate(0,0);transform:translate(0,0)}100%{-webkit-transform:translate(100%,0);transform:translate(100%,0)}}@keyframes rtl-drawer-out{0%{-webkit-transform:translate(0,0);transform:translate(0,0)}100%{-webkit-transform:translate(100%,0);transform:translate(100%,0)}}@-webkit-keyframes ltr-drawer-in{0%{-webkit-transform:translate(-100%,0);transform:translate(-100%,0)}100%{-webkit-transform:translate(0,0);transform:translate(0,0)}}@keyframes ltr-drawer-in{0%{-webkit-transform:translate(-100%,0);transform:translate(-100%,0)}100%{-webkit-transform:translate(0,0);transform:translate(0,0)}}@-webkit-keyframes ltr-drawer-out{0%{-webkit-transform:translate(0,0);transform:translate(0,0)}100%{-webkit-transform:translate(-100%,0);transform:translate(-100%,0)}}@keyframes ltr-drawer-out{0%{-webkit-transform:translate(0,0);transform:translate(0,0)}100%{-webkit-transform:translate(-100%,0);transform:translate(-100%,0)}}@-webkit-keyframes ttb-drawer-in{0%{-webkit-transform:translate(0,-100%);transform:translate(0,-100%)}100%{-webkit-transform:translate(0,0);transform:translate(0,0)}}@keyframes ttb-drawer-in{0%{-webkit-transform:translate(0,-100%);transform:translate(0,-100%)}100%{-webkit-transform:translate(0,0);transform:translate(0,0)}}@-webkit-keyframes ttb-drawer-out{0%{-webkit-transform:translate(0,0);transform:translate(0,0)}100%{-webkit-transform:translate(0,-100%);transform:translate(0,-100%)}}@keyframes ttb-drawer-out{0%{-webkit-transform:translate(0,0);transform:translate(0,0)}100%{-webkit-transform:translate(0,-100%);transform:translate(0,-100%)}}@-webkit-keyframes btt-drawer-in{0%{-webkit-transform:translate(0,100%);transform:translate(0,100%)}100%{-webkit-transform:translate(0,0);transform:translate(0,0)}}@keyframes btt-drawer-in{0%{-webkit-transform:translate(0,100%);transform:translate(0,100%)}100%{-webkit-transform:translate(0,0);transform:translate(0,0)}}@-webkit-keyframes btt-drawer-out{0%{-webkit-transform:translate(0,0);transform:translate(0,0)}100%{-webkit-transform:translate(0,100%);transform:translate(0,100%)}}@keyframes btt-drawer-out{0%{-webkit-transform:translate(0,0);transform:translate(0,0)}100%{-webkit-transform:translate(0,100%);transform:translate(0,100%)}}.el-drawer{position:absolute;-webkit-box-sizing:border-box;box-sizing:border-box;background-color:#FFF;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;-webkit-box-shadow:0 8px 10px -5px rgba(0,0,0,.2),0 16px 24px 2px rgba(0,0,0,.14),0 6px 30px 5px rgba(0,0,0,.12);box-shadow:0 8px 10px -5px rgba(0,0,0,.2),0 16px 24px 2px rgba(0,0,0,.14),0 6px 30px 5px rgba(0,0,0,.12);overflow:hidden;outline:0}.el-drawer.rtl{-webkit-animation:rtl-drawer-out .3s;animation:rtl-drawer-out .3s;right:0}.el-drawer__open .el-drawer.rtl{-webkit-animation:rtl-drawer-in .3s 1ms;animation:rtl-drawer-in .3s 1ms}.el-drawer.ltr{-webkit-animation:ltr-drawer-out .3s;animation:ltr-drawer-out .3s;left:0}.el-drawer__open .el-drawer.ltr{-webkit-animation:ltr-drawer-in .3s 1ms;animation:ltr-drawer-in .3s 1ms}.el-drawer.ttb{-webkit-animation:ttb-drawer-out .3s;animation:ttb-drawer-out .3s;top:0}.el-drawer__open .el-drawer.ttb{-webkit-animation:ttb-drawer-in .3s 1ms;animation:ttb-drawer-in .3s 1ms}.el-drawer.btt{-webkit-animation:btt-drawer-out .3s;animation:btt-drawer-out .3s;bottom:0}.el-drawer__open .el-drawer.btt{-webkit-animation:btt-drawer-in .3s 1ms;animation:btt-drawer-in .3s 1ms}.el-drawer__wrapper{position:fixed;top:0;right:0;bottom:0;left:0;overflow:hidden;margin:0}.el-drawer__header{-webkit-box-align:center;-ms-flex-align:center;align-items:center;color:#72767b;display:-webkit-box;display:-ms-flexbox;display:flex;margin-bottom:32px;padding:20px 20px 0}.el-drawer__header>:first-child{-webkit-box-flex:1;-ms-flex:1;flex:1}.el-drawer__title{margin:0;-webkit-box-flex:1;-ms-flex:1;flex:1;line-height:inherit;font-size:1rem}.el-drawer__close-btn{border:none;cursor:pointer;font-size:20px;color:inherit;background-color:transparent}.el-drawer__body{-webkit-box-flex:1;-ms-flex:1;flex:1;overflow:auto}.el-drawer__body>*{-webkit-box-sizing:border-box;box-sizing:border-box}.el-drawer.ltr,.el-drawer.rtl{height:100%;top:0;bottom:0}.el-drawer__container{position:relative;top:0;bottom:0;height:100%}.el-drawer-fade-enter-active{-webkit-animation:el-drawer-fade-in .3s;animation:el-drawer-fade-in .3s}.el-drawer-fade-leave-active{animation:el-drawer-fade-in .3s reverse}
1
+ @-webkit-keyframes el-drawer-fade-in{0%{opacity:0}100%{opacity:1}}@keyframes el-drawer-fade-in{0%{opacity:0}100%{opacity:1}}@-webkit-keyframes rtl-drawer-in{0%{-webkit-transform:translate(100%,0);transform:translate(100%,0)}100%{-webkit-transform:translate(0,0);transform:translate(0,0)}}@keyframes rtl-drawer-in{0%{-webkit-transform:translate(100%,0);transform:translate(100%,0)}100%{-webkit-transform:translate(0,0);transform:translate(0,0)}}@-webkit-keyframes rtl-drawer-out{0%{-webkit-transform:translate(0,0);transform:translate(0,0)}100%{-webkit-transform:translate(100%,0);transform:translate(100%,0)}}@keyframes rtl-drawer-out{0%{-webkit-transform:translate(0,0);transform:translate(0,0)}100%{-webkit-transform:translate(100%,0);transform:translate(100%,0)}}@-webkit-keyframes ltr-drawer-in{0%{-webkit-transform:translate(-100%,0);transform:translate(-100%,0)}100%{-webkit-transform:translate(0,0);transform:translate(0,0)}}@keyframes ltr-drawer-in{0%{-webkit-transform:translate(-100%,0);transform:translate(-100%,0)}100%{-webkit-transform:translate(0,0);transform:translate(0,0)}}@-webkit-keyframes ltr-drawer-out{0%{-webkit-transform:translate(0,0);transform:translate(0,0)}100%{-webkit-transform:translate(-100%,0);transform:translate(-100%,0)}}@keyframes ltr-drawer-out{0%{-webkit-transform:translate(0,0);transform:translate(0,0)}100%{-webkit-transform:translate(-100%,0);transform:translate(-100%,0)}}@-webkit-keyframes ttb-drawer-in{0%{-webkit-transform:translate(0,-100%);transform:translate(0,-100%)}100%{-webkit-transform:translate(0,0);transform:translate(0,0)}}@keyframes ttb-drawer-in{0%{-webkit-transform:translate(0,-100%);transform:translate(0,-100%)}100%{-webkit-transform:translate(0,0);transform:translate(0,0)}}@-webkit-keyframes ttb-drawer-out{0%{-webkit-transform:translate(0,0);transform:translate(0,0)}100%{-webkit-transform:translate(0,-100%);transform:translate(0,-100%)}}@keyframes ttb-drawer-out{0%{-webkit-transform:translate(0,0);transform:translate(0,0)}100%{-webkit-transform:translate(0,-100%);transform:translate(0,-100%)}}@-webkit-keyframes btt-drawer-in{0%{-webkit-transform:translate(0,100%);transform:translate(0,100%)}100%{-webkit-transform:translate(0,0);transform:translate(0,0)}}@keyframes btt-drawer-in{0%{-webkit-transform:translate(0,100%);transform:translate(0,100%)}100%{-webkit-transform:translate(0,0);transform:translate(0,0)}}@-webkit-keyframes btt-drawer-out{0%{-webkit-transform:translate(0,0);transform:translate(0,0)}100%{-webkit-transform:translate(0,100%);transform:translate(0,100%)}}@keyframes btt-drawer-out{0%{-webkit-transform:translate(0,0);transform:translate(0,0)}100%{-webkit-transform:translate(0,100%);transform:translate(0,100%)}}.el-drawer{position:absolute;-webkit-box-sizing:border-box;box-sizing:border-box;background-color:#FFF;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;-webkit-box-shadow:0 8px 10px -5px rgba(0,0,0,.2),0 16px 24px 2px rgba(0,0,0,.14),0 6px 30px 5px rgba(0,0,0,.12);box-shadow:0 8px 10px -5px rgba(0,0,0,.2),0 16px 24px 2px rgba(0,0,0,.14),0 6px 30px 5px rgba(0,0,0,.12);overflow:hidden;outline:0}.el-drawer.rtl{-webkit-animation:rtl-drawer-out .3s;animation:rtl-drawer-out .3s;right:0}.el-drawer__open .el-drawer.rtl{-webkit-animation:rtl-drawer-in .3s 1ms;animation:rtl-drawer-in .3s 1ms}.el-drawer.ltr{-webkit-animation:ltr-drawer-out .3s;animation:ltr-drawer-out .3s;left:0}.el-drawer__open .el-drawer.ltr{-webkit-animation:ltr-drawer-in .3s 1ms;animation:ltr-drawer-in .3s 1ms}.el-drawer.ttb{-webkit-animation:ttb-drawer-out .3s;animation:ttb-drawer-out .3s;top:0}.el-drawer__open .el-drawer.ttb{-webkit-animation:ttb-drawer-in .3s 1ms;animation:ttb-drawer-in .3s 1ms}.el-drawer.btt{-webkit-animation:btt-drawer-out .3s;animation:btt-drawer-out .3s;bottom:0}.el-drawer__open .el-drawer.btt{-webkit-animation:btt-drawer-in .3s 1ms;animation:btt-drawer-in .3s 1ms}.el-drawer__wrapper{position:fixed;top:0;right:0;bottom:0;left:0;overflow:hidden;margin:0}.el-drawer__wrapper-reference{position:absolute;top:0;right:0;bottom:0;left:0;overflow:hidden;margin:0}.el-drawer__header{-webkit-box-align:center;-ms-flex-align:center;align-items:center;color:#72767b;display:-webkit-box;display:-ms-flexbox;display:flex;margin-bottom:32px;padding:20px 20px 0}.el-drawer__header>:first-child{-webkit-box-flex:1;-ms-flex:1;flex:1}.el-drawer__title{margin:0;-webkit-box-flex:1;-ms-flex:1;flex:1;line-height:inherit;font-size:1rem}.el-drawer__close-btn{border:none;cursor:pointer;font-size:20px;color:inherit;background-color:transparent}.el-drawer__body{-webkit-box-flex:1;-ms-flex:1;flex:1;overflow:auto}.el-drawer__body>*{-webkit-box-sizing:border-box;box-sizing:border-box}.el-drawer.ltr,.el-drawer.rtl{height:100%;top:0;bottom:0}.el-drawer.btt,.el-drawer.ttb{width:100%;left:0;right:0}.el-drawer.is-reference{position:absolute}.el-drawer.is-reference.btt,.el-drawer.is-reference.ltr,.el-drawer.is-reference.rtl,.el-drawer.is-reference.ttb{height:auto;width:auto;top:auto;bottom:auto;left:auto;right:auto}.el-drawer__container{position:relative;left:0;right:0;top:0;bottom:0;height:100%;width:100%}.el-drawer__container.el-drawer__reference-mode{position:absolute;background-color:transparent;pointer-events:none}.el-drawer__container.el-drawer__reference-mode .el-drawer{pointer-events:auto}.el-drawer-fade-enter-active{-webkit-animation:el-drawer-fade-in .3s;animation:el-drawer-fade-in .3s}.el-drawer-fade-leave-active{animation:el-drawer-fade-in .3s reverse}