mdm-client 1.0.3 → 1.0.5

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 (36) hide show
  1. package/package.json +1 -1
  2. package/src/App.vue +72 -67
  3. package/src/assets/image/common/layout-active16.png +0 -0
  4. package/src/assets/image/common/layout-active25.png +0 -0
  5. package/src/assets/image/common/layout-active3.png +0 -0
  6. package/src/assets/image/common/layout-active9.png +0 -0
  7. package/src/assets/image/common/layout16.png +0 -0
  8. package/src/assets/image/common/layout25.png +0 -0
  9. package/src/assets/image/common/layout3.png +0 -0
  10. package/src/assets/image/common/layout9.png +0 -0
  11. package/src/assets/image/common/mirror.png +0 -0
  12. package/src/assets/image/common/rotate_icon1.png +0 -0
  13. package/src/assets/image/common/rotate_icon2.png +0 -0
  14. package/src/assets/image/common/rotate_icon3.png +0 -0
  15. package/src/assets/image/common/rotate_icon4.png +0 -0
  16. package/src/assets/style/base.scss +5 -0
  17. package/src/components/LiveMulti/LiveMulti.vue +27 -6
  18. package/src/components/LiveMultipleMeeting/LiveMultipleMeeting.vue +1163 -99
  19. package/src/components/LiveMultipleMeeting/style/index.scss +145 -14
  20. package/src/components/LivePoint/LivePoint.vue +71 -208
  21. package/src/components/LivePointMeeting/LivePointMeeting.vue +223 -13
  22. package/src/components/LivePointMeeting/style/index.scss +35 -0
  23. package/src/components/MeetingReadyDialog/MeetingReadyDialog.vue +96 -14
  24. package/src/components/MiniumVideoDialog/MiniumVideoDialog.vue +185 -50
  25. package/src/components/other/addressBook.vue +137 -20
  26. package/src/components/other/appointDialog.vue +1 -1
  27. package/src/components/other/customLayout.vue +368 -202
  28. package/src/components/other/layoutSwitch.vue +253 -37
  29. package/src/components/other/leadershipFocus.vue +422 -0
  30. package/src/components/other/leaveOptionDialog.vue +1 -1
  31. package/src/components/other/moreOptionDialog.vue +17 -1
  32. package/src/components/other/screenShareBoard.vue +2 -2
  33. package/src/components/other/selectDialog.vue +1 -1
  34. package/src/components/other/selectSpecialDialog.vue +1 -1
  35. package/src/utils/api.js +19 -0
  36. package/src/utils/livekit/live-client-esm.js +1 -1
@@ -1,3 +1,11 @@
1
+ @keyframes rotate {
2
+ from {
3
+ transform: rotate(0deg);
4
+ }
5
+ to {
6
+ transform: rotate(360deg);
7
+ }
8
+ }
1
9
  // 会议室样式
2
10
  // 通用样式
3
11
  .meeting {
@@ -7,6 +15,7 @@
7
15
  // border: 1px solid #798BA4;
8
16
  border-radius: 5px;
9
17
  margin: 5px;
18
+ overflow: hidden; // 旋转后裁剪溢出内容,避免页面出现“怪异”形态
10
19
  .p-video {
11
20
  position: absolute;
12
21
  width: 100%;
@@ -16,6 +25,33 @@
16
25
  z-index: 10;
17
26
  object-fit: contain;
18
27
  border-radius: 5px;
28
+ backface-visibility: hidden; // 避免3D旋转引发的锯齿闪烁
29
+ will-change: transform; // 提示浏览器优化旋转
30
+ }
31
+ .loadingIndicator {
32
+ position: absolute;
33
+ z-index: 20;
34
+ width: 100%;
35
+ height: 100%;
36
+ left: 0;
37
+ top: 0;
38
+ display: flex;
39
+ flex-direction: column;
40
+ align-items: center;
41
+ justify-content: center;
42
+ .loading-icon {
43
+ height: 20%;
44
+ width: auto;
45
+ border-radius: 50%;
46
+ aspect-ratio: 1/1;
47
+ background: var(--meeting-loading-icon) no-repeat center / 100% 100%;
48
+ animation: rotate 2s linear infinite;
49
+ }
50
+ .loading-text {
51
+ font-size: 14px;
52
+ line-height: 22px;
53
+ color: var(--theme-font-color);
54
+ }
19
55
  }
20
56
  .board {
21
57
  position: absolute;
@@ -120,6 +156,43 @@
120
156
  min-height: 30px;
121
157
  background: var(--more-icon) no-repeat center / 100% 100%;
122
158
  }
159
+ .rotate-icon {
160
+ visibility: hidden;
161
+ cursor: pointer;
162
+ position: absolute;
163
+ bottom: 10px;
164
+ right: 14px;
165
+ z-index: 50;
166
+ aspect-ratio: 1/1;
167
+ width: auto;
168
+ height: 5%;
169
+ min-height: 30px;
170
+ &1 {
171
+ background: var(--rotate-icon1) no-repeat center / 100% 100%;
172
+ }
173
+ &2 {
174
+ background: var(--rotate-icon2) no-repeat center / 100% 100%;
175
+ }
176
+ &3 {
177
+ background: var(--rotate-icon3) no-repeat center / 100% 100%;
178
+ }
179
+ &4 {
180
+ background: var(--rotate-icon4) no-repeat center / 100% 100%;
181
+ }
182
+ }
183
+ .bitrate-indicator {
184
+ display: none;
185
+ position: absolute;
186
+ top: 10px;
187
+ left: 50px; /* Position next to the signal icon */
188
+ z-index: 60;
189
+ padding: 4px 8px;
190
+ background-color: rgba(0, 0, 0, 0.6);
191
+ color: var(--theme-font-color, #ffffff);
192
+ font-size: 12px;
193
+ border-radius: 4px;
194
+ white-space: nowrap;
195
+ }
123
196
  }
124
197
  }
125
198
  // 宫格布局
@@ -130,11 +203,11 @@
130
203
  .participant {
131
204
  width: 100%;
132
205
  height: 98%;
133
- .p-video {
134
- object-fit: cover !important;
135
- }
206
+ // .p-video {
207
+ // object-fit: contain !important;
208
+ // }
136
209
  }
137
- .describe{
210
+ .describe {
138
211
  transform: scale(1.3);
139
212
  }
140
213
  }
@@ -148,7 +221,7 @@
148
221
  height: auto;
149
222
  aspect-ratio: 16/9;
150
223
  }
151
- .describe{
224
+ .describe {
152
225
  transform: scale(1.1);
153
226
  }
154
227
  }
@@ -163,7 +236,7 @@
163
236
  max-height: calc(50% - 10px);
164
237
  aspect-ratio: 16/9;
165
238
  }
166
- .describe{
239
+ .describe {
167
240
  transform: scale(1.1);
168
241
  }
169
242
  }
@@ -177,7 +250,7 @@
177
250
  height: auto;
178
251
  aspect-ratio: 16/9;
179
252
  }
180
- .describe{
253
+ .describe {
181
254
  transform: scale(0.9);
182
255
  }
183
256
  }
@@ -199,11 +272,10 @@
199
272
  max-height: calc(33.33% - 10px);
200
273
  aspect-ratio: 16/9;
201
274
  }
202
- .describe{
275
+ .describe {
203
276
  transform: scale(0.9);
204
277
  }
205
278
  }
206
-
207
279
  }
208
280
  .grid6 {
209
281
  display: flex;
@@ -213,10 +285,10 @@
213
285
  .participant {
214
286
  width: calc(25% - 10px);
215
287
  height: auto;
216
- max-height: calc(33.33% - 10px);
288
+ max-height: calc(25% - 10px);
217
289
  aspect-ratio: 16/9;
218
290
  }
219
- .describe{
291
+ .describe {
220
292
  transform: scale(0.75);
221
293
  }
222
294
  }
@@ -226,12 +298,12 @@
226
298
  justify-content: center;
227
299
  align-content: center;
228
300
  .participant {
229
- width: calc(25% - 10px);
301
+ width: calc(20% - 10px);
230
302
  height: auto;
231
- max-height: calc(25% - 10px);
303
+ max-height: calc(20% - 10px);
232
304
  aspect-ratio: 16/9;
233
305
  }
234
- .describe{
306
+ .describe {
235
307
  transform: scale(0.75);
236
308
  }
237
309
  }
@@ -334,4 +406,63 @@
334
406
  &-other {
335
407
  display: none;
336
408
  }
409
+ }
410
+ // 环形布局(非 scoped,适配动态创建的 DOM)
411
+ .layout-ring {
412
+ width: 100%;
413
+ height: 100%;
414
+ display: flex;
415
+ flex-direction: column;
416
+ gap: 8px;
417
+ box-sizing: border-box;
418
+
419
+ &-top {
420
+ display: grid;
421
+ grid-template-columns: repeat(4, 1fr);
422
+ grid-template-rows: repeat(4, 1fr);
423
+ gap: 5px;
424
+ align-items: center;
425
+ justify-items: center;
426
+ box-sizing: border-box;
427
+ position: relative;
428
+
429
+ .ring-slot {
430
+ width: 100%;
431
+ height: 100%;
432
+ display: flex;
433
+ align-items: center;
434
+ justify-content: center;
435
+ box-sizing: border-box;
436
+ .participant {
437
+ width: 100%;
438
+ height: 100%;
439
+ }
440
+ }
441
+
442
+ .ring-center {
443
+ grid-column: 2 / span 2;
444
+ grid-row: 2 / span 2;
445
+ width: 100%;
446
+ height: 100%;
447
+ display: flex;
448
+ align-items: center;
449
+ justify-content: center;
450
+ box-sizing: border-box;
451
+ .participant {
452
+ width: 100%;
453
+ height: 100%;
454
+ }
455
+ }
456
+ }
457
+
458
+ &-bottom {
459
+ display: grid;
460
+ grid-template-columns: repeat(4, 1fr);
461
+ grid-auto-rows: 1fr;
462
+ gap: 5px;
463
+ box-sizing: border-box;
464
+ .participant {
465
+ aspect-ratio: 16/9;
466
+ }
467
+ }
337
468
  }
@@ -1,6 +1,54 @@
1
1
  <template>
2
2
  <div class="live-point">
3
- <!-- Components will be mounted to body using custom mounting -->
3
+ <teleport to="body">
4
+ <LiveCallBoard
5
+ v-if="model"
6
+ :default-call-num="defaultCallNum"
7
+ @voiceCall="makeVoiceCall"
8
+ @videoCall="makeVideoCall"
9
+ @miniCall="makeMiniCall"
10
+ @callBoardClose="model = false"
11
+ ></LiveCallBoard>
12
+ </teleport>
13
+ <teleport to="body">
14
+ <LiveInviteReceive
15
+ v-if="isInviteReceiveShow"
16
+ :inviteData="inviteData"
17
+ @receiveBoardClose="inviteReceiveClose"
18
+ @acceptInviteCall="acceptInviteCall"
19
+ @refuseInviteCall="refuseInviteCall"
20
+ >
21
+ </LiveInviteReceive>
22
+ </teleport>
23
+ <teleport to="body">
24
+ <LivePointMeeting
25
+ v-if="isMeetingDialogShow"
26
+ ref="livePointMeetingRef"
27
+ :joinType="pointMeetingData.joinType"
28
+ :meetingNum="pointMeetingData.meetingNum"
29
+ :meetingType="pointMeetingData.meetingType"
30
+ :inviteName="pointMeetingData.inviteName"
31
+ :inviteType="pointMeetingData.inviteType"
32
+ :invitePhone="pointMeetingData.invitePhone"
33
+ :inviteWays="inviteWays"
34
+ :inviteUserData="inviteUserData"
35
+ :isInMeeting="isInMeeting"
36
+ @meetingDialogClose="meetingDialogClose"
37
+ @miniLinkSend="miniLinkSend"
38
+ @meetingStarted="isInMeeting = true"
39
+ @meetingEnded="isInMeeting = false"
40
+ @pointMeetingMinum="openMiniVideoDialog"
41
+ >
42
+ </LivePointMeeting>
43
+ </teleport>
44
+ <teleport to="body">
45
+ <minium-video-dialog
46
+ v-if="isMiniVideoDialogShow"
47
+ :trackData="trackData"
48
+ @resetMultiDialog="resetPointDialog"
49
+ @miniVideoDialogClose="closeMiniVideoDialog"
50
+ ></minium-video-dialog>
51
+ </teleport>
4
52
  </div>
5
53
  </template>
6
54
 
@@ -10,6 +58,8 @@ import { mittBus, ShowMessage } from "../../utils/index.js";
10
58
  import LiveCallBoard from "../LiveCallBoard/LiveCallBoard.vue";
11
59
  import LivePointMeeting from "../LivePointMeeting/LivePointMeeting.vue";
12
60
  import LiveInviteReceive from "../LiveInviteReceive/LiveInviteReceive.vue";
61
+ import MiniumVideoDialog from "../MiniumVideoDialog/MiniumVideoDialog.vue";
62
+ import Teleport from 'vue2-teleport'
13
63
 
14
64
  export default {
15
65
  name: "LivePoint",
@@ -17,6 +67,8 @@ export default {
17
67
  LiveCallBoard,
18
68
  LivePointMeeting,
19
69
  LiveInviteReceive,
70
+ MiniumVideoDialog,
71
+ Teleport
20
72
  },
21
73
  props: {
22
74
  defaultCallNum: {
@@ -52,13 +104,8 @@ export default {
52
104
  isInMeeting: false,
53
105
  liveClient: null,
54
106
  showMessage: null,
55
- // DOM mounting references
56
- callBoardInstance: null,
57
- inviteReceiveInstance: null,
58
- pointMeetingInstance: null,
59
- callBoardContainer: null,
60
- inviteReceiveContainer: null,
61
- pointMeetingContainer: null,
107
+ isMiniVideoDialogShow: false,
108
+ trackData: {}
62
109
  };
63
110
  },
64
111
  computed: {
@@ -75,15 +122,10 @@ export default {
75
122
  this.showMessage = new ShowMessage();
76
123
  this.handleLiveClientInitSuccess();
77
124
  mittBus.on("liveClientInitSuccess", this.handleLiveClientInitSuccess);
78
-
79
- // Initialize DOM containers for body mounting
80
- this.createMountContainers();
125
+
81
126
  },
82
127
  beforeDestroy() {
83
128
  mittBus.off("liveClientInitSuccess", this.handleLiveClientInitSuccess);
84
-
85
- // Clean up mounted components
86
- this.destroyMountedComponents();
87
129
  },
88
130
  methods: {
89
131
  // 对外暴露方法, 发起PC会议
@@ -96,7 +138,7 @@ export default {
96
138
  this.isMeetingDialogShow = true;
97
139
  },
98
140
  // volte语音外呼
99
- makeVoiceCall({ inviteName, invitePhone, inviteType = 0 } = {}) {
141
+ makeVoiceCall({ inviteName, invitePhone, inviteType = 0 } = e) {
100
142
  this.pointMeetingData.joinType = "launch";
101
143
  this.pointMeetingData.meetingType = "voice";
102
144
  this.pointMeetingData.invitePhone = invitePhone;
@@ -106,7 +148,7 @@ export default {
106
148
  this.isMeetingDialogShow = true;
107
149
  },
108
150
  // volte视频外呼
109
- makeVideoCall({ inviteName, invitePhone, inviteType = 0 } = {}) {
151
+ makeVideoCall({ inviteName, invitePhone, inviteType = 0 } = e) {
110
152
  this.pointMeetingData.joinType = "launch";
111
153
  this.pointMeetingData.meetingType = "video";
112
154
  this.pointMeetingData.invitePhone = invitePhone;
@@ -116,7 +158,7 @@ export default {
116
158
  this.isMeetingDialogShow = true;
117
159
  },
118
160
  // 通过小程序邀请
119
- makeMiniCall({ inviteName, invitePhone, inviteType = 0 } = {}) {
161
+ makeMiniCall({ inviteName, invitePhone, inviteType = 0 } = e) {
120
162
  this.pointMeetingData.joinType = "launch";
121
163
  this.pointMeetingData.meetingType = "miniLink";
122
164
  this.pointMeetingData.invitePhone = invitePhone;
@@ -126,7 +168,7 @@ export default {
126
168
  this.isMeetingDialogShow = true;
127
169
  },
128
170
  inviteReceiveClose() {
129
- this.$emit("inviteReceiveClose");
171
+ this.$emit("inviteReceiveClose")
130
172
  },
131
173
  // 点击接收按钮
132
174
  acceptInviteCall(e) {
@@ -137,7 +179,7 @@ export default {
137
179
  this.pointMeetingData.joinType = "join";
138
180
  this.pointMeetingData.meetingType = e.isVoice == 1 ? "voice" : "video";
139
181
  this.pointMeetingData.meetingNum = e.roomNum;
140
- this.isMeetingDialogShow = true;
182
+ this.isMeetingDialogShow.value = true;
141
183
  this.inviteReceiveClose();
142
184
  } else {
143
185
  this.showMessage.message("error", res?.msg || "接受会议邀请失败,请重试");
@@ -170,203 +212,24 @@ export default {
170
212
  meetingDialogClose() {
171
213
  this.isMeetingDialogShow = false;
172
214
  },
173
- handleCallBoardClose() {
174
- this.model = false;
215
+ openMiniVideoDialog(e) {
216
+ this.trackData = e ?? {}
217
+ this.isMiniVideoDialogShow = true
175
218
  },
176
- handleMeetingStarted() {
177
- this.isInMeeting = true;
219
+ resetPointDialog() {
220
+ this.isMiniVideoDialogShow = false
221
+ this.$refs.livePointMeetingRef && this.$refs.livePointMeetingRef.resetDialog()
178
222
  },
179
- handleMeetingEnded() {
180
- this.isInMeeting = false;
223
+ closeMiniVideoDialog() {
224
+ this.isMiniVideoDialogShow = false
181
225
  },
182
226
  handleLiveClientInitSuccess() {
183
227
  this.liveClient = window["liveClient"];
184
- },
185
-
186
- // Create mount containers for body mounting (replacing Teleport)
187
- createMountContainers() {
188
- // CallBoard container
189
- this.callBoardContainer = document.createElement('div');
190
- this.callBoardContainer.id = 'live-call-board-container';
191
-
192
- // InviteReceive container
193
- this.inviteReceiveContainer = document.createElement('div');
194
- this.inviteReceiveContainer.id = 'live-invite-receive-container';
195
-
196
- // PointMeeting container
197
- this.pointMeetingContainer = document.createElement('div');
198
- this.pointMeetingContainer.id = 'live-point-meeting-container';
199
- },
200
-
201
- // Mount CallBoard component to body
202
- mountCallBoard() {
203
- if (!this.callBoardContainer || document.getElementById('live-call-board-container')) return;
204
-
205
- document.body.appendChild(this.callBoardContainer);
206
-
207
- const CallBoardConstructor = Vue.extend(LiveCallBoard);
208
- this.callBoardInstance = new CallBoardConstructor({
209
- propsData: {
210
- defaultCallNum: this.defaultCallNum
211
- }
212
- });
213
-
214
- this.callBoardInstance.$on('voiceCall', this.makeVoiceCall);
215
- this.callBoardInstance.$on('videoCall', this.makeVideoCall);
216
- this.callBoardInstance.$on('miniCall', this.makeMiniCall);
217
- this.callBoardInstance.$on('callBoardClose', this.handleCallBoardClose);
218
-
219
- this.callBoardInstance.$mount(this.callBoardContainer);
220
- },
221
-
222
- // Mount InviteReceive component to body
223
- mountInviteReceive() {
224
- if (!this.inviteReceiveContainer || document.getElementById('live-invite-receive-container')) return;
225
-
226
- if (!this.isInviteReceiveShow) return;
227
-
228
- document.body.appendChild(this.inviteReceiveContainer);
229
-
230
- const InviteReceiveConstructor = Vue.extend(LiveInviteReceive);
231
- this.inviteReceiveInstance = new InviteReceiveConstructor({
232
- propsData: {
233
- inviteData: this.inviteData
234
- }
235
- });
236
-
237
- this.inviteReceiveInstance.$on('receiveBoardClose', this.inviteReceiveClose);
238
- this.inviteReceiveInstance.$on('acceptInviteCall', this.acceptInviteCall);
239
- this.inviteReceiveInstance.$on('refuseInviteCall', this.refuseInviteCall);
240
-
241
- this.inviteReceiveInstance.$mount(this.inviteReceiveContainer);
242
- },
243
-
244
- // Mount PointMeeting component to body
245
- mountPointMeeting() {
246
- if (!this.pointMeetingContainer || document.getElementById('live-point-meeting-container')) return;
247
-
248
- if (!this.isMeetingDialogShow) return;
249
-
250
- document.body.appendChild(this.pointMeetingContainer);
251
-
252
- const PointMeetingConstructor = Vue.extend(LivePointMeeting);
253
- this.pointMeetingInstance = new PointMeetingConstructor({
254
- propsData: {
255
- joinType: this.pointMeetingData.joinType,
256
- meetingNum: this.pointMeetingData.meetingNum,
257
- meetingType: this.pointMeetingData.meetingType,
258
- inviteName: this.pointMeetingData.inviteName,
259
- inviteType: this.pointMeetingData.inviteType,
260
- invitePhone: this.pointMeetingData.invitePhone,
261
- inviteWays: this.inviteWays,
262
- inviteUserData: this.inviteUserData
263
- }
264
- });
265
-
266
- this.pointMeetingInstance.$on('meetingDialogClose', this.meetingDialogClose);
267
- this.pointMeetingInstance.$on('miniLinkSend', this.miniLinkSend);
268
- this.pointMeetingInstance.$on('meetingStarted', this.handleMeetingStarted);
269
- this.pointMeetingInstance.$on('meetingEnded', this.handleMeetingEnded);
270
-
271
- this.pointMeetingInstance.$mount(this.pointMeetingContainer);
272
- },
273
-
274
- // Unmount CallBoard component
275
- unmountCallBoard() {
276
- if (this.callBoardInstance) {
277
- this.callBoardInstance.$destroy();
278
- this.callBoardInstance.$el.remove();
279
- this.callBoardInstance = null;
280
- }
281
- if (this.callBoardContainer && this.callBoardContainer.parentNode) {
282
- this.callBoardContainer.parentNode.removeChild(this.callBoardContainer);
283
- }
284
- },
285
-
286
- // Unmount InviteReceive component
287
- unmountInviteReceive() {
288
- if (this.inviteReceiveInstance) {
289
- this.inviteReceiveInstance.$destroy();
290
- this.inviteReceiveInstance.$el.remove();
291
- this.inviteReceiveInstance = null;
292
- }
293
- if (this.inviteReceiveContainer && this.inviteReceiveContainer.parentNode) {
294
- this.inviteReceiveContainer.parentNode.removeChild(this.inviteReceiveContainer);
295
- }
296
- },
297
-
298
- // Unmount PointMeeting component
299
- unmountPointMeeting() {
300
- if (this.pointMeetingInstance) {
301
- this.pointMeetingInstance.$destroy();
302
- this.pointMeetingInstance.$el.remove();
303
- this.pointMeetingInstance = null;
304
- }
305
- if (this.pointMeetingContainer && this.pointMeetingContainer.parentNode) {
306
- this.pointMeetingContainer.parentNode.removeChild(this.pointMeetingContainer);
307
- }
308
- },
309
-
310
- // Clean up all mounted components
311
- destroyMountedComponents() {
312
- this.unmountCallBoard();
313
- this.unmountInviteReceive();
314
- this.unmountPointMeeting();
315
- },
228
+ }
316
229
  },
317
-
318
230
  watch: {
319
- model(newVal) {
320
- if (newVal) {
321
- this.$nextTick(() => {
322
- this.mountCallBoard();
323
- });
324
- } else {
325
- this.unmountCallBoard();
326
- }
327
- },
328
-
329
- isInviteReceiveShow(newVal) {
330
- if (newVal) {
331
- this.$nextTick(() => {
332
- this.mountInviteReceive();
333
- });
334
- } else {
335
- this.unmountInviteReceive();
336
- }
337
- },
338
-
339
- isMeetingDialogShow(newVal) {
340
- if (newVal) {
341
- this.$nextTick(() => {
342
- this.mountPointMeeting();
343
- });
344
- } else {
345
- this.unmountPointMeeting();
346
- }
347
- },
348
-
349
- inviteData: {
350
- handler(newVal) {
351
- if (this.inviteReceiveInstance) {
352
- this.inviteReceiveInstance.inviteData = newVal;
353
- }
354
- },
355
- deep: true
356
- },
357
-
358
- pointMeetingData: {
359
- handler(newVal) {
360
- if (this.pointMeetingInstance) {
361
- Object.keys(newVal).forEach(key => {
362
- this.pointMeetingInstance[key] = newVal[key];
363
- });
364
- }
365
- },
366
- deep: true
367
- }
368
231
  }
369
232
  };
370
233
  </script>
371
234
 
372
- <style lang="scss" scoped></style>
235
+ <style lang="scss" scoped></style>