vue-element-ui-x 1.0.42-beta → 1.0.51

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 (90) hide show
  1. package/lib/index.common.js +1 -1
  2. package/lib/index.esm.js +1 -1
  3. package/lib/index.js +20 -17
  4. package/lib/index.umd.js +1 -1
  5. package/lib/mixins/index.js +20 -17
  6. package/package.json +5 -5
  7. package/src/components/Attachments/index.js +0 -8
  8. package/src/components/Attachments/src/main.vue +0 -529
  9. package/src/components/Bubble/index.js +0 -6
  10. package/src/components/Bubble/src/main.vue +0 -288
  11. package/src/components/BubbleList/index.js +0 -8
  12. package/src/components/BubbleList/src/loading.vue +0 -75
  13. package/src/components/BubbleList/src/main.vue +0 -444
  14. package/src/components/Conversations/index.js +0 -8
  15. package/src/components/Conversations/src/components/item.vue +0 -350
  16. package/src/components/Conversations/src/main.vue +0 -587
  17. package/src/components/FilesCard/index.js +0 -8
  18. package/src/components/FilesCard/src/fileSvg/audio.vue +0 -38
  19. package/src/components/FilesCard/src/fileSvg/changeFileName.bat +0 -18
  20. package/src/components/FilesCard/src/fileSvg/code.vue +0 -35
  21. package/src/components/FilesCard/src/fileSvg/database.vue +0 -94
  22. package/src/components/FilesCard/src/fileSvg/excel.vue +0 -38
  23. package/src/components/FilesCard/src/fileSvg/file.vue +0 -40
  24. package/src/components/FilesCard/src/fileSvg/image.vue +0 -40
  25. package/src/components/FilesCard/src/fileSvg/index.js +0 -46
  26. package/src/components/FilesCard/src/fileSvg/link.vue +0 -54
  27. package/src/components/FilesCard/src/fileSvg/mark.vue +0 -38
  28. package/src/components/FilesCard/src/fileSvg/pdf.vue +0 -38
  29. package/src/components/FilesCard/src/fileSvg/ppt.vue +0 -38
  30. package/src/components/FilesCard/src/fileSvg/three.vue +0 -38
  31. package/src/components/FilesCard/src/fileSvg/txt.vue +0 -38
  32. package/src/components/FilesCard/src/fileSvg/unknown.vue +0 -54
  33. package/src/components/FilesCard/src/fileSvg/video.vue +0 -38
  34. package/src/components/FilesCard/src/fileSvg/word.vue +0 -38
  35. package/src/components/FilesCard/src/fileSvg/zip.vue +0 -38
  36. package/src/components/FilesCard/src/main.vue +0 -403
  37. package/src/components/FilesCard/src/options.js +0 -18
  38. package/src/components/Prompts/index.js +0 -8
  39. package/src/components/Prompts/src/main.vue +0 -248
  40. package/src/components/Sender/index.js +0 -8
  41. package/src/components/Sender/src/components/ClearButton.vue +0 -28
  42. package/src/components/Sender/src/components/Loading.vue +0 -53
  43. package/src/components/Sender/src/components/LoadingButton.vue +0 -37
  44. package/src/components/Sender/src/components/SendButton.vue +0 -26
  45. package/src/components/Sender/src/components/SpeechButton.vue +0 -24
  46. package/src/components/Sender/src/components/SpeechLoading.vue +0 -87
  47. package/src/components/Sender/src/components/SpeechLoadingButton.vue +0 -41
  48. package/src/components/Sender/src/main.vue +0 -803
  49. package/src/components/Thinking/index.js +0 -8
  50. package/src/components/Thinking/src/main.vue +0 -199
  51. package/src/components/ThoughtChain/index.js +0 -8
  52. package/src/components/ThoughtChain/src/main.vue +0 -291
  53. package/src/components/Typewriter/index.js +0 -8
  54. package/src/components/Typewriter/src/main.vue +0 -255
  55. package/src/components/Welcome/index.js +0 -8
  56. package/src/components/Welcome/src/main.vue +0 -151
  57. package/src/index.js +0 -104
  58. package/src/locale/index.js +0 -97
  59. package/src/locale/lang/ar.js +0 -18
  60. package/src/locale/lang/de.js +0 -18
  61. package/src/locale/lang/en.js +0 -18
  62. package/src/locale/lang/es.js +0 -18
  63. package/src/locale/lang/fr.js +0 -18
  64. package/src/locale/lang/index.js +0 -62
  65. package/src/locale/lang/it.js +0 -18
  66. package/src/locale/lang/ja.js +0 -18
  67. package/src/locale/lang/ko.js +0 -18
  68. package/src/locale/lang/pt-br.js +0 -18
  69. package/src/locale/lang/ru-RU.js +0 -18
  70. package/src/locale/lang/zh-CN.js +0 -18
  71. package/src/locale/lang/zh-TW.js +0 -18
  72. package/src/locale/mixin.js +0 -9
  73. package/src/mixins/index.js +0 -49
  74. package/src/mixins/recordMixin.js +0 -117
  75. package/src/mixins/sendMixin.js +0 -450
  76. package/src/mixins/streamMixin.js +0 -497
  77. package/src/styles/Attachments.scss +0 -236
  78. package/src/styles/Bubble.scss +0 -158
  79. package/src/styles/BubbleList.scss +0 -148
  80. package/src/styles/Conversations.scss +0 -283
  81. package/src/styles/FilesCard.scss +0 -222
  82. package/src/styles/Prompts.scss +0 -197
  83. package/src/styles/Sender.scss +0 -211
  84. package/src/styles/Thinking.scss +0 -142
  85. package/src/styles/ThoughtChain.scss +0 -113
  86. package/src/styles/Typewriter.scss +0 -66
  87. package/src/styles/Welcome.scss +0 -283
  88. package/src/theme/var.scss +0 -183
  89. package/src/utils/index.js +0 -199
  90. package/src/utils/scrollDetector.js +0 -34
@@ -290,35 +290,19 @@ class XRequest {
290
290
  if (!line.trim()) {
291
291
  return;
292
292
  }
293
-
294
293
  // 处理 data: 开头的行
295
294
  if (line.startsWith('data: ')) {
296
295
  const dataContent = line.slice(6);
297
-
298
- // 检查是否是结束标识
299
- if (dataContent.trim() === '[DONE]') {
300
- this._isFinished = true;
301
- this._onFinish && this._onFinish(this._messages);
302
- this.abort();
303
- return;
304
- }
305
-
306
- // 跳过空数据
307
296
  if (!dataContent.trim()) {
308
297
  return;
309
298
  }
310
299
  try {
311
- // 尝试解析和处理数据
312
300
  let processedData;
313
301
  try {
314
- // 首先尝试作为 JSON 解析
315
302
  processedData = JSON.parse(dataContent);
316
303
  } catch {
317
- // 如果不是 JSON,使用原始数据
318
304
  processedData = dataContent;
319
305
  }
320
- // console.log('processedData:', processedData, processedData.answer);
321
-
322
306
  const res = this._transformer ? this._transformer(processedData) : processedData;
323
307
  this._messages.push(res);
324
308
  this._onMessage && this._onMessage(res);
@@ -327,8 +311,27 @@ class XRequest {
327
311
  this._onError && this._onError(error);
328
312
  this._controller && this._controller.abort();
329
313
  }
314
+ return;
315
+ }
316
+
317
+ // 处理其他 SSE 标准字段
318
+ // if (line.startsWith('event: ') || line.startsWith('id: ') || line.startsWith('retry: ')) {
319
+ // console.log('SSE control field:', line);
320
+ // return;
321
+ // }
322
+
323
+ // 兜底处理
324
+ if (line.trim()) {
325
+ try {
326
+ const res = this._transformer ? this._transformer(line) : line;
327
+ this._messages.push(res);
328
+ this._onMessage && this._onMessage(res);
329
+ } catch (error) {
330
+ console.error('Error processing non-SSE line:', line, error);
331
+ this._onError && this._onError(error);
332
+ this._controller && this._controller.abort();
333
+ }
330
334
  }
331
- // 可以在这里处理其他类型的行(如果需要)
332
335
  }
333
336
 
334
337
  /**
package/package.json CHANGED
@@ -1,12 +1,11 @@
1
1
  {
2
2
  "name": "vue-element-ui-x",
3
- "version": "1.0.42-beta",
3
+ "version": "1.0.51",
4
4
  "description": "基于Vue 2 + Element UI的AI聊天组件库",
5
5
  "module": "lib/index.esm.js",
6
6
  "main": "lib/index.common.js",
7
7
  "files": [
8
8
  "lib",
9
- "src",
10
9
  "components.json",
11
10
  "package.json",
12
11
  "README.md"
@@ -50,9 +49,10 @@
50
49
  "vue": "^2.6.14"
51
50
  },
52
51
  "devDependencies": {
53
- "@babel/plugin-transform-arrow-functions": "^7.27.1",
54
- "@babel/plugin-transform-block-scoping": "^7.28.0",
55
- "@babel/preset-env": "^7.28.0",
52
+ "@babel/core": "^7.16.0",
53
+ "@babel/preset-env": "^7.16.0",
54
+ "@babel/plugin-transform-arrow-functions": "^7.16.0",
55
+ "@babel/plugin-transform-block-scoping": "^7.16.0",
56
56
  "babel-loader": "^8.2.3",
57
57
  "cross-env": "^7.0.3",
58
58
  "css-loader": "^5.2.7",
@@ -1,8 +0,0 @@
1
- import ElXAttachments from './src/main.vue';
2
-
3
- /* istanbul ignore next */
4
- ElXAttachments.install = function (Vue) {
5
- Vue.component(ElXAttachments.name, ElXAttachments);
6
- };
7
-
8
- export default ElXAttachments;
@@ -1,529 +0,0 @@
1
- <template>
2
- <div
3
- ref="wrapperRef"
4
- class="el-x-attachments-wrapper"
5
- :class="{
6
- 'el-x-attachments-overflow-ping-start': overflow === 'scrollX' && pingStart,
7
- 'el-x-attachments-overflow-ping-end': overflow === 'scrollX' && pingEnd,
8
- }"
9
- :style="{
10
- ...listStyle,
11
- '--el-x-attachments-upload-icon-size': uploadIconSize,
12
- }"
13
- >
14
- <div v-if="!items.length && !hideUpload">
15
- <slot name="empty-upload">
16
- <el-upload
17
- class="el-x-attachments-upload-btn"
18
- v-bind="$attrs"
19
- :action="uploadAction"
20
- :http-request="customUpload"
21
- :show-file-list="false"
22
- :on-change="handleUploadChange"
23
- :on-success="handleUploadSuccess"
24
- :on-error="handleUploadError"
25
- >
26
- <i class="el-icon-plus uploader-icon"></i>
27
- </el-upload>
28
- </slot>
29
- </div>
30
-
31
- <div class="el-x-attachments-background">
32
- <div
33
- v-if="overflow === 'scrollX' && pingStart"
34
- class="el-x-attachments-background-start"
35
- />
36
- <div
37
- v-if="overflow === 'scrollX' && pingEnd"
38
- class="el-x-attachments-background-end"
39
- />
40
- </div>
41
-
42
- <div
43
- ref="containerRef"
44
- class="el-x-attachments"
45
- :class="{
46
- [`el-x-attachments-overflow-${overflow}`]: overflow,
47
- }"
48
- :style="{
49
- ...(overflow === 'scrollX'
50
- ? { whiteSpace: 'nowrap', overflowX: 'auto', overflowY: 'hidden' }
51
- : {}),
52
- ...(overflow === 'scrollY' ? { overflowX: 'hidden', overflowY: 'auto' } : {}),
53
- ...(overflow === 'wrap' ? { display: 'flex', flexWrap: 'wrap' } : {}),
54
- }"
55
- @scroll="debouncedCheckPing"
56
- >
57
- <div
58
- v-if="items.length"
59
- :class="{
60
- 'el-x-attachments-file-card-wrap': overflow === 'scrollX',
61
- }"
62
- >
63
- <slot
64
- name="file-list"
65
- :items="items"
66
- >
67
- <div
68
- v-for="(item, index) in items"
69
- :key="item.uid"
70
- class="el-x-attachments-card"
71
- >
72
- <transition name="card-motion">
73
- <el-x-files-card
74
- v-if="item.uid"
75
- v-bind="item"
76
- class="el-x-attachments-card-item"
77
- @delete="handleDelete(item, index)"
78
- />
79
- </transition>
80
- </div>
81
- </slot>
82
-
83
- <div
84
- v-if="items.length && !isOverLimit && !hideUpload"
85
- class="el-x-attachments-upload-placeholder"
86
- >
87
- <slot name="no-empty-upload">
88
- <el-upload
89
- v-bind="$attrs"
90
- :action="uploadAction"
91
- :http-request="customUpload"
92
- :show-file-list="false"
93
- :style="{
94
- height: overflow === 'scrollY' && '',
95
- }"
96
- class="el-x-attachments-upload-btn"
97
- :on-change="handleUploadChange"
98
- :on-success="handleUploadSuccess"
99
- :on-error="handleUploadError"
100
- >
101
- <i class="el-icon-plus uploader-icon"></i>
102
- </el-upload>
103
- </slot>
104
- </div>
105
- </div>
106
- </div>
107
-
108
- <slot
109
- name="prev-button"
110
- :show="overflow === 'scrollX' && pingStart"
111
- :on-scroll-left="onScrollLeft"
112
- >
113
- <el-button
114
- v-if="overflow === 'scrollX' && pingStart"
115
- size="small"
116
- class="el-x-attachments-prev-btn"
117
- @click="onScrollLeft"
118
- >
119
- <i class="el-icon-arrow-left"></i>
120
- </el-button>
121
- </slot>
122
-
123
- <slot
124
- name="next-button"
125
- :show="overflow === 'scrollX' && pingEnd"
126
- :on-scroll-right="onScrollRight"
127
- >
128
- <el-button
129
- v-if="overflow === 'scrollX' && pingEnd"
130
- size="small"
131
- class="el-x-attachments-next-btn"
132
- @click="onScrollRight"
133
- >
134
- <i class="el-icon-arrow-right"></i>
135
- </el-button>
136
- </slot>
137
-
138
- <!-- 使用传统 DOM 放置方式代替 Teleport -->
139
- <div
140
- v-if="isTargetDrag"
141
- ref="dropAreaContainer"
142
- style="display: none"
143
- >
144
- <slot name="drop-area">
145
- <div
146
- ref="dropAreaRef"
147
- class="el-x-attachments-drop-area"
148
- >
149
- <i class="el-icon-upload el-x-attachments-drop-area-icon"></i>
150
- <div class="el-x-attachments-drop-area-text">在此处拖放文件上传</div>
151
- </div>
152
- </slot>
153
- </div>
154
- </div>
155
- </template>
156
-
157
- <script>
158
- import ElXFilesCard from '../../FilesCard';
159
-
160
- export default {
161
- name: 'ElXAttachments',
162
- components: { ElXFilesCard },
163
- props: {
164
- items: {
165
- type: Array,
166
- default: () => [],
167
- },
168
- overflow: {
169
- type: String,
170
- default: 'scrollX',
171
- },
172
- listStyle: {
173
- type: Object,
174
- default: () => ({}),
175
- },
176
- uploadIconSize: {
177
- type: String,
178
- default: '64px',
179
- },
180
- dragTarget: {
181
- type: [String, Object, HTMLElement],
182
- default: undefined,
183
- },
184
- hideUpload: {
185
- type: Boolean,
186
- default: false,
187
- },
188
- limit: {
189
- type: Number,
190
- default: undefined,
191
- },
192
- uploadAction: {
193
- type: String,
194
- default: '#',
195
- },
196
- },
197
- data() {
198
- return {
199
- containerRef: null,
200
- wrapperRef: null,
201
- firstMount: false,
202
- pingStart: false,
203
- pingEnd: false,
204
- TOLERANCE: 1,
205
- // 上传相关
206
- targetElement: null,
207
- isTargetDrag: false,
208
- dropAreaRef: null,
209
- dropAreaContainer: null,
210
- };
211
- },
212
- computed: {
213
- isOverLimit() {
214
- if (this.limit && this.items.length >= this.limit) {
215
- return true;
216
- }
217
- return false;
218
- },
219
- },
220
- mounted() {
221
- this.firstMount = true;
222
- this.$nextTick(() => this.debouncedCheckPing());
223
- window.addEventListener('resize', this.debouncedCheckPing);
224
-
225
- // 如果有拖拽目标元素,则监听拖拽事件
226
- if (this.$refs.wrapperRef) {
227
- this.targetElement = this.getTargetElement() || this.$refs.wrapperRef;
228
-
229
- // 监听拖拽事件
230
- this.targetElement.addEventListener('dragenter', this.targetDragEnter, false);
231
- this.targetElement.addEventListener('dragleave', this.targetDropLeave, false);
232
- this.targetElement.addEventListener('drop', this.targetDrop, false);
233
- this.targetElement.addEventListener('dragover', this.targetDragOver, false);
234
- }
235
- },
236
- beforeDestroy() {
237
- window.removeEventListener('resize', this.debouncedCheckPing);
238
- if (this.targetElement) {
239
- this.targetElement.removeEventListener('dragenter', this.targetDragEnter, false);
240
- this.targetElement.removeEventListener('dragleave', this.targetDropLeave, false);
241
- this.targetElement.removeEventListener('drop', this.targetDrop, false);
242
- this.targetElement.removeEventListener('dragover', this.targetDragOver, false);
243
- }
244
-
245
- // 清理可能存在的 dropArea 元素
246
- this.removeDragArea();
247
- },
248
- watch: {
249
- 'items.length': function () {
250
- this.$nextTick(() => this.debouncedCheckPing());
251
- },
252
- overflow: function () {
253
- this.$nextTick(() => this.debouncedCheckPing());
254
- },
255
- dragTarget: function () {
256
- this.$nextTick(() => {
257
- // 如果有拖拽目标元素,则监听拖拽事件
258
- if (this.$refs.wrapperRef) {
259
- if (this.targetElement) {
260
- this.targetElement.removeEventListener('dragenter', this.targetDragEnter, false);
261
- this.targetElement.removeEventListener('dragleave', this.targetDropLeave, false);
262
- this.targetElement.removeEventListener('drop', this.targetDrop, false);
263
- this.targetElement.removeEventListener('dragover', this.targetDragOver, false);
264
- }
265
-
266
- this.targetElement = this.getTargetElement() || this.$refs.wrapperRef;
267
-
268
- // 监听拖拽事件
269
- this.targetElement.addEventListener('dragenter', this.targetDragEnter, false);
270
- this.targetElement.addEventListener('dragleave', this.targetDropLeave, false);
271
- this.targetElement.addEventListener('drop', this.targetDrop, false);
272
- this.targetElement.addEventListener('dragover', this.targetDragOver, false);
273
- }
274
- });
275
- },
276
- isTargetDrag: function (newVal) {
277
- if (newVal) {
278
- this.appendDragArea();
279
- } else {
280
- this.removeDragArea();
281
- }
282
- },
283
- },
284
- methods: {
285
- // 列表相关方法
286
- checkPing() {
287
- const containerEle = this.$refs.containerRef;
288
- if (!containerEle) return;
289
-
290
- if (this.overflow === 'scrollX') {
291
- this.pingStart = Math.abs(containerEle.scrollLeft) >= this.TOLERANCE;
292
- this.pingEnd =
293
- containerEle.scrollWidth -
294
- containerEle.clientWidth -
295
- Math.abs(containerEle.scrollLeft) >=
296
- this.TOLERANCE;
297
- } else if (this.overflow === 'scrollY') {
298
- this.pingStart = containerEle.scrollTop !== 0;
299
- this.pingEnd =
300
- containerEle.scrollHeight - containerEle.clientHeight !== containerEle.scrollTop;
301
- } else {
302
- this.pingStart = false;
303
- this.pingEnd = false;
304
- }
305
- },
306
- onScrollOffset(offset) {
307
- const containerEle = this.$refs.containerRef;
308
- if (containerEle) {
309
- containerEle.scrollTo({
310
- left:
311
- this.overflow === 'scrollX'
312
- ? containerEle.scrollLeft + offset * containerEle.clientWidth
313
- : containerEle.scrollLeft,
314
- top:
315
- this.overflow === 'scrollY'
316
- ? containerEle.scrollTop + offset * containerEle.clientHeight
317
- : containerEle.scrollTop,
318
- behavior: 'smooth',
319
- });
320
- }
321
- },
322
- onScrollLeft() {
323
- this.onScrollOffset(-1);
324
- },
325
- onScrollRight() {
326
- this.onScrollOffset(1);
327
- },
328
- // 防抖函数
329
- debounce(func, wait) {
330
- let timeout;
331
- return function () {
332
- const context = this;
333
- const args = arguments;
334
- clearTimeout(timeout);
335
- timeout = setTimeout(() => {
336
- func.apply(context, args);
337
- }, wait);
338
- };
339
- },
340
-
341
- customUpload(options) {
342
- // 自定义上传方法,如果父组件提供了http-request,则使用父组件的
343
- if (this.$attrs['http-request']) {
344
- return this.$attrs['http-request'](options);
345
- }
346
-
347
- // 默认实现:发出事件,让父组件处理
348
- const { file } = options;
349
- this.$emit('upload-change', { file }, [file]);
350
-
351
- // 如果需要模拟上传进度和成功/失败状态,可以在此实现
352
- // 例如:options.onProgress({ percent: 50 })
353
- // options.onSuccess({ url: 'https://example.com/file.jpg' })
354
- // 或者 options.onError(new Error('Upload failed'))
355
-
356
- // 由于我们只是返回事件,不实际上传,所以直接返回一个空Promise
357
- return Promise.resolve();
358
- },
359
- handleUploadChange(file, fileList) {
360
- this.$emit('upload-change', file, fileList);
361
- },
362
- handleUploadSuccess(response, file, fileList) {
363
- this.$emit('upload-success', response, file, fileList);
364
- },
365
- handleUploadError(error, file, fileList) {
366
- this.$emit('upload-error', error, file, fileList);
367
- },
368
-
369
- getTargetElement() {
370
- if (!this.dragTarget) return this.$refs.wrapperRef;
371
-
372
- // 处理原生 DOM 元素(如 document.body)
373
- if (this.dragTarget instanceof HTMLElement) {
374
- return this.dragTarget;
375
- }
376
-
377
- if (typeof this.dragTarget === 'string') {
378
- return document.getElementById(this.dragTarget);
379
- }
380
-
381
- // Vue2 中获取引用
382
- if (this.dragTarget && this.dragTarget.$el) {
383
- return this.dragTarget.$el;
384
- }
385
-
386
- // 兜底返回 wrapperRef
387
- return this.$refs.wrapperRef;
388
- },
389
- // 修改拖拽样式切换方法
390
- toggleDragStyle(isDrag) {
391
- console.log('toggleDragStyle called:', isDrag); // 调试用,可以删除
392
-
393
- this.isTargetDrag = isDrag;
394
-
395
- if (this.targetElement) {
396
- const isBodyTarget = this.targetElement === document.body;
397
-
398
- if (isDrag) {
399
- // 立即显示拖拽区域
400
- this.$nextTick(() => {
401
- this.appendDragArea();
402
- });
403
-
404
- if (isBodyTarget && this.$refs.dropAreaRef) {
405
- this.$refs.dropAreaRef.style.position = 'fixed';
406
- this.$refs.dropAreaRef.style.width = '100vw';
407
- this.$refs.dropAreaRef.style.height = '100vh';
408
- this.$refs.dropAreaRef.style.left = '0';
409
- this.$refs.dropAreaRef.style.top = '0';
410
- this.$refs.dropAreaRef.style.zIndex = '9999';
411
- } else {
412
- this.targetElement.style.position = 'relative';
413
- }
414
- } else {
415
- // 延迟移除拖拽区域,避免闪烁
416
- setTimeout(() => {
417
- this.removeDragArea();
418
- }, 100);
419
-
420
- if (!isBodyTarget) {
421
- this.targetElement.style.position = '';
422
- }
423
- }
424
- }
425
- },
426
- // 修改事件处理方法
427
- targetDragEnter(event) {
428
- event.preventDefault();
429
- event.stopPropagation();
430
-
431
- // 移除防抖,直接执行
432
- this.toggleDragStyle(true);
433
- },
434
- targetDropLeave(event) {
435
- event.preventDefault();
436
- event.stopPropagation();
437
-
438
- const relatedTarget = event.relatedTarget;
439
-
440
- // 如果离开后进入的元素仍在目标元素内部,或者进入了拖拽区域本身,不执行样式移除
441
- if (
442
- this.targetElement &&
443
- (this.targetElement.contains(relatedTarget) ||
444
- (this.$refs.dropAreaRef && this.$refs.dropAreaRef.contains(relatedTarget)))
445
- ) {
446
- return;
447
- }
448
-
449
- // 移除防抖,直接执行
450
- this.toggleDragStyle(false);
451
- },
452
- targetDrop(event) {
453
- event.preventDefault();
454
- event.stopPropagation();
455
-
456
- // 立即移除拖拽样式
457
- this.toggleDragStyle(false);
458
-
459
- if (event.dataTransfer) {
460
- const files = event.dataTransfer.files;
461
- if (files.length) {
462
- const filesArray = [];
463
- for (let i = 0; i < files.length; i++) {
464
- filesArray.push(files[i]);
465
- }
466
- this.$emit('upload-drop', filesArray, Object.assign({}, this.$props));
467
- }
468
- }
469
- },
470
- targetDragOver(event) {
471
- event.preventDefault();
472
- event.stopPropagation();
473
- },
474
- // 卡片相关方法
475
- handleDelete(item, index) {
476
- this.$emit('delete-card', item, index);
477
- this.$nextTick(() => this.debouncedCheckPing());
478
- },
479
- // 修改 DOM 操作方法
480
- appendDragArea() {
481
- if (!this.$refs.dropAreaRef || !this.targetElement) {
482
- return;
483
- }
484
-
485
- // 确保元素已经渲染
486
- this.$nextTick(() => {
487
- const dragAreaNode = this.$refs.dropAreaRef;
488
-
489
- // 检查是否已经添加过了
490
- if (dragAreaNode.parentNode !== this.targetElement) {
491
- // 显示容器
492
- if (this.$refs.dropAreaContainer) {
493
- this.$refs.dropAreaContainer.style.display = 'block';
494
- }
495
-
496
- // 添加到目标元素
497
- this.targetElement.appendChild(dragAreaNode);
498
-
499
- // 强制重绘
500
- dragAreaNode.offsetHeight;
501
- }
502
- });
503
- },
504
- removeDragArea() {
505
- if (!this.$refs.dropAreaRef || !this.targetElement) {
506
- return;
507
- }
508
-
509
- const dragAreaNode = this.$refs.dropAreaRef;
510
-
511
- if (dragAreaNode.parentNode === this.targetElement) {
512
- this.targetElement.removeChild(dragAreaNode);
513
- }
514
-
515
- // 隐藏容器
516
- if (this.$refs.dropAreaContainer) {
517
- this.$refs.dropAreaContainer.style.display = 'none';
518
- }
519
- },
520
- },
521
- created() {
522
- this.debouncedCheckPing = this.debounce(this.checkPing, 100);
523
- },
524
- };
525
- </script>
526
-
527
- <style lang="scss" scoped>
528
- @import '../../../styles/Attachments.scss';
529
- </style>
@@ -1,6 +0,0 @@
1
- import ElXBubble from './src/main.vue';
2
- /* istanbul ignore next */
3
- ElXBubble.install = function (Vue) {
4
- Vue.component(ElXBubble.name, ElXBubble);
5
- };
6
- export default ElXBubble;