vue2-client 1.20.65 → 1.20.66

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.
@@ -1,11 +1,7 @@
1
1
  <?xml version="1.0" encoding="UTF-8"?>
2
2
  <module type="WEB_MODULE" version="4">
3
3
  <component name="NewModuleRootManager">
4
- <content url="file://$MODULE_DIR$">
5
- <excludeFolder url="file://$MODULE_DIR$/.tmp" />
6
- <excludeFolder url="file://$MODULE_DIR$/temp" />
7
- <excludeFolder url="file://$MODULE_DIR$/tmp" />
8
- </content>
4
+ <content url="file://$MODULE_DIR$" />
9
5
  <orderEntry type="inheritedJdk" />
10
6
  <orderEntry type="sourceFolder" forTests="false" />
11
7
  </component>
@@ -2,5 +2,22 @@
2
2
  <profile version="1.0">
3
3
  <option name="myName" value="Project Default" />
4
4
  <inspection_tool class="Eslint" enabled="true" level="WARNING" enabled_by_default="true" />
5
+ <inspection_tool class="HtmlUnknownTag" enabled="true" level="WARNING" enabled_by_default="true">
6
+ <option name="myValues">
7
+ <value>
8
+ <list size="7">
9
+ <item index="0" class="java.lang.String" itemvalue="nobr" />
10
+ <item index="1" class="java.lang.String" itemvalue="noembed" />
11
+ <item index="2" class="java.lang.String" itemvalue="comment" />
12
+ <item index="3" class="java.lang.String" itemvalue="noscript" />
13
+ <item index="4" class="java.lang.String" itemvalue="embed" />
14
+ <item index="5" class="java.lang.String" itemvalue="script" />
15
+ <item index="6" class="java.lang.String" itemvalue="a-descriptions-item" />
16
+ </list>
17
+ </value>
18
+ </option>
19
+ <option name="myCustomValuesEnabled" value="true" />
20
+ </inspection_tool>
21
+ <inspection_tool class="UsePropertyAccessSyntax" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
5
22
  </profile>
6
23
  </component>
@@ -0,0 +1,12 @@
1
+ 2026-03-18 10:11:17 - afgit.config - INFO - 开始推送配置
2
+ 2026-03-18 10:11:17 - afgit.config - INFO - 开始推送配置文件(含新增与修改),目录: ./config_files
3
+ 2026-03-18 10:11:17 - afgit.config - DEBUG - 开始认证,URL: http://192.168.50.67:31467/api/af-auth/login, 用户名: 1
4
+ 2026-03-18 10:11:18 - afgit.config - ERROR - 解析认证响应失败: {"code":400,"data":null,"error":true,"msg":"用户不存在/密码错误","success":false}, 用户名: 1, 密码: Class123!@!
5
+ 2026-03-18 10:11:18 - afgit.config - ERROR - 认证失败,推送终止
6
+ 2026-03-18 10:11:18 - afgit.config - ERROR - 推送配置失败
7
+ 2026-03-18 10:11:24 - afgit.config - INFO - 开始拉取最新配置
8
+ 2026-03-18 10:11:24 - afgit.config - INFO - 开始下载配置文件到: ./config_files
9
+ 2026-03-18 10:11:24 - afgit.config - DEBUG - 开始认证,URL: http://192.168.50.67:31467/api/af-auth/login, 用户名: 1
10
+ 2026-03-18 10:11:25 - afgit.config - ERROR - 解析认证响应失败: {"code":400,"data":null,"error":true,"msg":"用户不存在/密码错误","success":false}, 用户名: 1, 密码: Class123!@!
11
+ 2026-03-18 10:11:25 - afgit.config - ERROR - 认证失败,下载终止
12
+ 2026-03-18 10:11:25 - afgit.config - ERROR - 拉取配置失败
@@ -0,0 +1,7 @@
1
+ 2026-02-27 09:24:44 - afgit.config - INFO - 开始拉取最新配置
2
+ 2026-02-27 09:24:44 - afgit.config - INFO - 创建本地目录: ./config_files
3
+ 2026-02-27 09:24:44 - afgit.config - INFO - 开始下载配置文件到: ./config_files
4
+ 2026-02-27 09:24:44 - afgit.config - DEBUG - 开始认证,URL: http://192.168.50.67:31467/api/af-auth/login, 用户名: 1
5
+ 2026-02-27 09:24:44 - afgit.config - ERROR - 解析认证响应失败: {"code":400,"data":null,"error":true,"msg":"用户不存在/密码错误","success":false}, 用户名: 1, 密码: Class123!@!
6
+ 2026-02-27 09:24:44 - afgit.config - ERROR - 认证失败,下载终止
7
+ 2026-02-27 09:24:44 - afgit.config - ERROR - 拉取配置失败
@@ -0,0 +1,6 @@
1
+ 2026-03-18 10:11:18 - afgit.config - ERROR - 解析认证响应失败: {"code":400,"data":null,"error":true,"msg":"用户不存在/密码错误","success":false}, 用户名: 1, 密码: Class123!@!
2
+ 2026-03-18 10:11:18 - afgit.config - ERROR - 认证失败,推送终止
3
+ 2026-03-18 10:11:18 - afgit.config - ERROR - 推送配置失败
4
+ 2026-03-18 10:11:25 - afgit.config - ERROR - 解析认证响应失败: {"code":400,"data":null,"error":true,"msg":"用户不存在/密码错误","success":false}, 用户名: 1, 密码: Class123!@!
5
+ 2026-03-18 10:11:25 - afgit.config - ERROR - 认证失败,下载终止
6
+ 2026-03-18 10:11:25 - afgit.config - ERROR - 拉取配置失败
@@ -0,0 +1,3 @@
1
+ 2026-02-27 09:24:44 - afgit.config - ERROR - 解析认证响应失败: {"code":400,"data":null,"error":true,"msg":"用户不存在/密码错误","success":false}, 用户名: 1, 密码: Class123!@!
2
+ 2026-02-27 09:24:44 - afgit.config - ERROR - 认证失败,下载终止
3
+ 2026-02-27 09:24:44 - afgit.config - ERROR - 拉取配置失败
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vue2-client",
3
- "version": "1.20.65",
3
+ "version": "1.20.66",
4
4
  "private": false,
5
5
  "scripts": {
6
6
  "serve": "SET NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service serve --no-eslint",
@@ -2,51 +2,31 @@
2
2
  <a-card :bordered="false">
3
3
  <x-form-table
4
4
  title="示例表单"
5
- queryParamsName="scanCodeAndNFCRUD"
5
+ :queryParamsName="queryParamsName"
6
6
  :fixedAddForm="fixedAddForm"
7
7
  :externalSelectedRowKeys="selectedKeys"
8
- :defaultPageSize="100"
9
- :pageSizeArray="['100','200']"
10
8
  @action="action"
11
9
  @selectRow="selectRow"
12
10
  @columnClick="columnClick"
13
11
  @ceshi="ceshi"
14
- @startService="startService"
15
- serviceName="af-safecheck"
12
+ @rowDblClick="rowDblClick"
13
+ serviceName="af-revenue"
16
14
  ref="xFormTable"
17
15
  :reserveSpaceForButtons="true"
18
- >
19
- </x-form-table>
20
- <a-modal
21
- v-model="formModalVisible"
22
- title="工单回访"
23
- :zIndex="1002"
24
- width="50vw"
25
- :destroy-on-close="true"
26
- @cancel="formModalVisible = false"
27
- @ok="ok"
28
- >
29
- <x-add-native-form
30
- ref="xForm"
31
- />
32
- </a-modal>
33
- <button @click="backDealData">提交</button>
16
+ @addFormSubmit="addFormSubmit"
17
+ ></x-form-table>
34
18
  </a-card>
35
19
  </template>
36
20
 
37
21
  <script>
38
22
  import XFormTable from '@vue2-client/base-client/components/common/XFormTable/XFormTable.vue'
39
- import XAddNativeForm from '@vue2-client/base-client/components/common/XAddNativeForm/XAddNativeForm.vue'
40
23
  import { microDispatch } from '@vue2-client/utils/microAppUtils'
41
- import {getConfigByNameAsync, runLogic} from '@vue2-client/services/api/common'
42
-
43
24
  export default {
44
25
  name: 'Demo',
45
26
  components: {
46
- XFormTable,
47
- XAddNativeForm,
27
+ XFormTable
48
28
  },
49
- data () {
29
+ data() {
50
30
  return {
51
31
  // 查询配置文件名
52
32
  queryParamsName: 'ceshiCRUD',
@@ -62,32 +42,26 @@ export default {
62
42
  selectedKeys: [],
63
43
  selected: {
64
44
  keys: [],
65
- rows: [],
66
- },
67
- formModalVisible: false,
45
+ rows: []
46
+ }
68
47
  }
69
48
  },
49
+
70
50
  methods: {
71
- backDealData () {
72
- this.$refs.xFormTable.$refs.xForm.backDealData().then(data => {
73
- console.log('backDealData', data)
74
- console.log('selected', this.$refs.xFormTable.$refs.xForm?.form)
51
+ handleCustomQuery() {
52
+ this.$refs.xFormTable.queryTable({
53
+ uf_f_alias: 'XianFeng',
54
+ uf_f_card_id: '10500030'
75
55
  })
76
56
  },
57
+ rowDblClick(record) {
58
+ console.log('rowDblClick', record)
59
+ },
77
60
  // input框 行編輯參數傳遞
78
- ceshi (...args) {
61
+ ceshi(...args) {
79
62
  // attr, value, currentRecord, currentIndex, nextRecord, nextIndex
80
- const [attr, value, currentRecord, currentIndex, nextRecord, nextIndex] =
81
- args
82
- console.log(
83
- 'ceshi',
84
- attr,
85
- value,
86
- currentRecord,
87
- currentIndex,
88
- nextRecord,
89
- nextIndex
90
- )
63
+ const [attr, value, currentRecord, currentIndex, nextRecord, nextIndex] = args
64
+ console.log('ceshi', attr, value, currentRecord, currentIndex, nextRecord, nextIndex)
91
65
  // 示例:当按下 Enter 键且有下一行时,跳转到下一行的同一列
92
66
  // 可以在这里执行业务逻辑(例如:保存数据)
93
67
  console.log('当前行:', currentIndex, '下一行:', nextIndex)
@@ -98,115 +72,45 @@ export default {
98
72
  // 跳转到下一行的同一列
99
73
  this.$refs.xFormTable.$refs.xTable.focusInput(nextIndex, attr.model)
100
74
  },
101
- test () {
75
+ test() {
102
76
  this.$refs.xFormTable.setTableData([])
103
77
  },
104
- defaultF () {
78
+ defaultF() {
105
79
  this.$refs.xFormTable.setTableSize('default')
106
80
  },
107
- middleF () {
81
+ middleF() {
108
82
  this.$refs.xFormTable.setTableSize('middle')
109
83
  },
110
- smallF () {
84
+ smallF() {
111
85
  this.$refs.xFormTable.setTableSize('small')
112
86
  },
113
- columnClick (key, value, record) {
87
+ columnClick(key, value, record) {
114
88
  microDispatch({
115
89
  type: 'v3route',
116
90
  path: '/bingliguanli/dianzibingliluru',
117
- props: { selected: arguments[0].his_f_admission_id },
91
+ props: { selected: arguments[0].his_f_admission_id }
118
92
  })
119
93
  },
120
- startService (record, id, actionType) {
121
- getConfigByNameAsync('测试Form', 'af-safecheck').then(config => {
122
- this.formModalVisible = true
123
- this.$nextTick(
124
- () => {
125
- this.formModalVisible = true
126
- this.$refs.xForm.init({
127
- formItems: config.formJson,
128
- title: '工单回访',
129
- businessType: '只读',
130
- ...config,
131
- fixedAddForm: {
132
- Images:[
133
- {
134
- 'uid': 1850,
135
- 'url': '/resource/af-system/images/3de85050493f4404ad3d0a00d53bca12.png',
136
- 'name': '3de85050493f4404ad3d0a00d53bca12.png'
137
- }
138
- ],
139
- f_image1:[
140
- {
141
- 'uid': 1850,
142
- 'url': '/resource/af-system/images/3de85050493f4404ad3d0a00d53bca12.png',
143
- 'name': '3de85050493f4404ad3d0a00d53bca12.png'
144
- }
145
- ],
146
- signs: [
147
- {
148
- 'uid': 1850,
149
- 'url': '/resource/af-system/images/3de85050493f4404ad3d0a00d53bca12.png',
150
- 'name': '3de85050493f4404ad3d0a00d53bca12.png'
151
- }
152
- ],
153
- },
154
- modifyModelData: {
155
- data: {
156
- Images:[
157
- {
158
- 'uid': 1850,
159
- 'url': '/resource/af-system/images/3de85050493f4404ad3d0a00d53bca12.png',
160
- 'name': '3de85050493f4404ad3d0a00d53bca12.png'
161
- }
162
- ],
163
- f_image1:[
164
- {
165
- 'uid': 1850,
166
- 'url': '/resource/af-system/images/3de85050493f4404ad3d0a00d53bca12.png',
167
- 'name': '3de85050493f4404ad3d0a00d53bca12.png'
168
- }
169
- ],
170
- f_image2: [
171
- {
172
- 'uid': 1850,
173
- 'url': '/resource/af-system/images/3de85050493f4404ad3d0a00d53bca12.png',
174
- 'name': '3de85050493f4404ad3d0a00d53bca12.png'
175
- }
176
- ],
177
- },
178
- signs: [
179
- {
180
- 'uid': 1850,
181
- 'url': '/resource/af-system/images/3de85050493f4404ad3d0a00d53bca12.png',
182
- 'name': '3de85050493f4404ad3d0a00d53bca12.png'
183
- }
184
- ],
185
- },
186
- })
187
- })
188
- })
189
- // this.detailVisible = true
190
- // console.log('触发了详情操作', record, id, actionType)
191
- },
192
- async ok () {
193
- const res = await this.$refs.xForm.asyncSubmit()
194
- await runLogic('ceshwewei', res.realForm)
94
+ action(record, id, actionType) {
95
+ this.detailVisible = true
96
+ console.log('触发了详情操作', record, id, actionType)
195
97
  },
196
- onClose () {
98
+ onClose() {
197
99
  this.detailVisible = false
198
100
  // 关闭详情之后重新查询表单
199
101
  this.$refs.xFormTable.refreshTable(true)
200
102
  },
201
- selectRow (selectedRowKeys, selectedRows) {
103
+ selectRow(selectedRowKeys, selectedRows) {
104
+ console.log('selectRow', selectedRowKeys, selectedRows)
202
105
  this.selected = {
203
106
  keys: selectedRowKeys,
204
- rows: selectedRows,
107
+ rows: selectedRows
205
108
  }
206
- console.log('selectedDemo', this.selected)
207
109
  },
208
- },
209
- computed: {},
110
+ addFormSubmit(params, callback){
111
+ callback()
112
+ }
113
+ }
210
114
  }
211
115
  </script>
212
116
 
@@ -220,6 +220,13 @@ export default {
220
220
  _configEndResolve: null,
221
221
  }
222
222
  },
223
+ inject: {
224
+ // 从祖先获取 getGridScopePath(可能是外层 XReport 或 XTab 提供的)
225
+ upstreamGetGridScopePath: {
226
+ from: 'getGridScopePath',
227
+ default: null
228
+ }
229
+ },
223
230
  beforeDestroy () {
224
231
  clearInterval(this.timer)
225
232
  if (this.$componentRegistry && this._globalRegistrySlotNames.length) {
@@ -233,6 +240,9 @@ export default {
233
240
  // 如果配置名更改了,重新获取配置
234
241
  configName (val) {
235
242
  if (val) {
243
+ // 先清空配置,避免异步期间使用旧配置注册快捷键
244
+ this.originalConfig = null
245
+ this.scanFinish = false
236
246
  getConfigByName(
237
247
  this.configName,
238
248
  undefined,
@@ -276,6 +286,20 @@ export default {
276
286
  closeAddReport: report.closeAddReport.bind(report),
277
287
  setData: report.setData.bind(report),
278
288
  getRootReport: () => report,
289
+ getGridScopePath: () => {
290
+ // 1. 优先从注入的上游函数获取父路径
291
+ let parent = ''
292
+ if (typeof report.upstreamGetGridScopePath === 'function') {
293
+ parent = report.upstreamGetGridScopePath()
294
+ }
295
+ // 2. 如果没有注入(根实例),回退到 prop(兼容旧写法)
296
+ if (!parent && report.parentScopePath) {
297
+ parent = report.parentScopePath
298
+ }
299
+ // 3. 拼上自己的 configName
300
+ const current = report.configName
301
+ return parent ? `${parent}/${current}` : current
302
+ }
279
303
  }
280
304
  },
281
305
  methods: {
@@ -186,9 +186,11 @@ import { getRealKeyData } from '@vue2-client/utils/util'
186
186
  import { executeStrFunctionByContext } from '@vue2-client/utils/runEvalFunction'
187
187
  import { getConfigByName, runLogic } from '@vue2-client/services/api/common'
188
188
  import { getMicroData, getWindow, isMicroAppEnv, microDispatch } from '@vue2-client/utils/microAppUtils'
189
+ import { shortcutMixin } from '@vue2-client/base-client/plugins/shortcutMixin'
189
190
 
190
191
  export default {
191
192
  name: 'XReportTrGroup',
193
+ mixins: [shortcutMixin],
192
194
  components: {
193
195
  Upload,
194
196
  XFormTable: () => import('@vue2-client/base-client/components/common/XFormTable/XFormTable.vue'),
@@ -315,6 +317,8 @@ export default {
315
317
  },
316
318
  data () {
317
319
  return {
320
+ // 快捷键作用域类型:grid 表示栅格类组件
321
+ shortcutScopeType: 'grid',
318
322
  gutter: [8, { xs: 8, sm: 16, md: 24, lg: 32 }], // 设置水槽大小
319
323
  maxColSpan: 12,
320
324
  uploadParams: {
@@ -367,6 +371,11 @@ export default {
367
371
  closeAddReport: { default: false },
368
372
  setData: { default: false },
369
373
  getRootReport: { default: false },
374
+ // 注入来自父组件(XReport)的栅格完整作用域路径(XReport已拼接完整)
375
+ getGridScopePath: { default: null }
376
+ },
377
+ beforeDestroy() {
378
+ this.unregisterShortcuts()
370
379
  },
371
380
  methods: {
372
381
  getWindow,
@@ -374,6 +383,128 @@ export default {
374
383
  microDispatch,
375
384
  getMicroData,
376
385
  getRealKeyData,
386
+ // ========== Mixin 覆盖方法 ==========
387
+ /**
388
+ * 获取快捷键配置(覆盖mixin)
389
+ * 验证当前激活的配置名是否匹配当前组件的配置名
390
+ */
391
+ getShortcutConfig() {
392
+ try {
393
+ let parent = ''
394
+ if (typeof this.getGridScopePath === 'function') {
395
+ parent = this.getGridScopePath()
396
+ }
397
+ const parts = parent.split('/')
398
+ return { columns: this.columns, configName: parts[parts.length - 1], scopeType: 'grid' }
399
+ }catch (e){
400
+ console.log('=============---->',e)
401
+ }
402
+ },
403
+
404
+
405
+ /**
406
+ * 获取组件实例(覆盖mixin,供快捷键上下文使用)
407
+ */
408
+ getScopePath() {
409
+ // 1. 获取路由
410
+ const route = this.$route?.path || 'unknown-route'
411
+
412
+ // 2. 获取 Tab 容器名称(来自 XTab)
413
+ let tabInfo = 'no-tab'
414
+ if (typeof this.getTabPath === 'function') {
415
+ const tabPath = this.getTabPath()
416
+ if (tabPath) {
417
+ tabInfo = tabPath
418
+ }
419
+ } else if (typeof this.getCurrentTabIndex === 'function') {
420
+ const tabIndex = this.getCurrentTabIndex()
421
+ if (tabIndex !== undefined && tabIndex !== null) {
422
+ tabInfo = `tab[${tabIndex}]`
423
+ }
424
+ }
425
+
426
+ // 3. 获取栅格配置名称 - 优先使用根组件的 configName,否则尝试 config 上的属性
427
+ let gridName = 'unknown-grid'
428
+ if (this._rootConfigName) {
429
+ gridName = this._rootConfigName
430
+ } else if (this.config) {
431
+ // 尝试 configName
432
+ if (this.config.configName) {
433
+ gridName = this.config.configName
434
+ }
435
+ // 尝试 configKey
436
+ else if (this.config.configKey) {
437
+ gridName = this.config.configKey
438
+ }
439
+ // 尝试 slotConfigName
440
+ else if (this.config.slotConfigName) {
441
+ gridName = this.config.slotConfigName
442
+ }
443
+ // 尝试 name
444
+ else if (this.config.name) {
445
+ gridName = this.config.name
446
+ }
447
+ // 尝试 title
448
+ else if (this.config.title) {
449
+ gridName = this.config.title
450
+ }
451
+ // 尝试从 columns 中的第一个 slot 获取 slotConfig(槽位名)
452
+ else if (this.config.columns && this.config.columns.length > 0) {
453
+ const firstRow = this.config.columns[0]
454
+ if (Array.isArray(firstRow) && firstRow.length > 0) {
455
+ const firstCell = firstRow[0]
456
+ if (firstCell?.slotConfig) {
457
+ gridName = `slot:${firstCell.slotConfig}`
458
+ } else if (firstCell?.slotRef) {
459
+ gridName = `ref:${firstCell.slotRef}`
460
+ }
461
+ }
462
+ }
463
+ }
464
+
465
+ // 调试:打印 config 的可用属性
466
+ if (this._scopePathDebugCount === undefined) {
467
+ this._scopePathDebugCount = 0
468
+ }
469
+ if (this._scopePathDebugCount < 3 && this.config) {
470
+ console.log(`[XReportTrGroup getScopePath] config keys:`, Object.keys(this.config), 'configName:', this.config.configName)
471
+ this._scopePathDebugCount++
472
+ }
473
+
474
+ // 完整路径:路由 -> Tab容器名称 -> 栅格配置名称
475
+ return `${route} -> ${tabInfo} -> ${gridName}`
476
+ },
477
+
478
+ /**
479
+ * 获取组件实例(覆盖mixin,供快捷键上下文使用)
480
+ */
481
+ shortcutGetComponent(ref) {
482
+ // 通过 $refs 查找动态组件
483
+ const refName = `dynamicComponent_${ref}`
484
+ const component = this.$refs[refName]?.[0]
485
+ console.log('【获取组件实例】',component)
486
+ if (component) {
487
+ // 尝试获取实例方法
488
+ if (component.getXTabInstance) return component.getXTabInstance()
489
+ if (component.getXFormTableInstance) return component.getXFormTableInstance()
490
+ if (component.getXAddNativeFormInstance) return component.getXAddNativeFormInstance()
491
+ return component
492
+ }
493
+ return null
494
+ },
495
+
496
+ /**
497
+ * 查找组件(覆盖mixin)
498
+ */
499
+ shortcutFindComponent(ref) {
500
+ console.log('【查找组件】', this)
501
+ console.log('【查找组件】', ref)
502
+ if (this.findComponentByName) {
503
+ return this.findComponentByName(this, ref, 10, 'parent')
504
+ }
505
+ return this.shortcutGetComponent(ref)
506
+ },
507
+ // ========== Mixin 覆盖方法结束 ==========
377
508
  handleRowClick (record) {
378
509
  this.$emit('rowClick', record)
379
510
  },
@@ -418,6 +549,11 @@ export default {
418
549
  this.$set(this.slotConfigEnded, cellIndex, true)
419
550
  if (Object.keys(this.slotConfigEnded).length >= this.allSlotSum) {
420
551
  this.$emit('slotsConfigEnded')
552
+ // 所有 slot 配置结束后,完整扫描一次快捷键
553
+ this.$nextTick(() => {
554
+ console.log('【所有 slot 配置结束后】 完整扫描一次快捷键')
555
+ this.rescanShortcuts()
556
+ })
421
557
  }
422
558
  },
423
559
  onComponentMounted (h, cell, cellIndex) {
@@ -435,6 +571,12 @@ export default {
435
571
  mountedLogicMode: cell.mountedLogicMode,
436
572
  mountedLogicParam: cell.mountedLogicParam
437
573
  })}
574
+ // 子组件挂载后,触发其快捷键注册
575
+ const component = this.$refs[`dynamicComponent_${cell.slotRef || cellIndex}`]?.[0]
576
+ console.log('【子组件挂载后,触发其快捷键注册】', component)
577
+ if (component && typeof component.onShortcutMixinReady === 'function') {
578
+ component.onShortcutMixinReady()
579
+ }
438
580
  // 传递给祖先组件
439
581
  const shouldInit = cell.shouldInit == null ? true : cell.shouldInit
440
582
  if (shouldInit) {
@@ -667,7 +809,7 @@ export default {
667
809
  })
668
810
 
669
811
  // 处理子节点样式
670
- this.parseNestedStyles(classConfig, childStyles)
812
+ this.parseNestedStyles(classConfig, childStyles)
671
813
  })
672
814
  return {
673
815
  rootStyles,
@@ -877,6 +1019,8 @@ export default {
877
1019
  mounted () {
878
1020
  this.$nextTick(() => {
879
1021
  if (this.allSlotSum === 0) this.$emit('slotsConfigEnded')
1022
+ // 挂载后注册快捷键
1023
+ this.registerShortcutsIfNeeded()
880
1024
  })
881
1025
  },
882
1026
  }