oxy-uni-ui 2.1.2 → 2.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/attributes.json +1 -1
- package/components/common/AbortablePromise.ts +4 -0
- package/components/common/abstracts/variable.scss +172 -66
- package/components/common/base64.ts +6 -0
- package/components/common/clickoutside.ts +5 -0
- package/components/common/interceptor.ts +9 -0
- package/components/common/path.ts +4 -0
- package/components/common/props.ts +23 -0
- package/components/common/util.ts +18 -1
- package/components/composables/index.ts +2 -0
- package/components/composables/useCell.ts +8 -1
- package/components/composables/useChildren.ts +27 -1
- package/components/composables/useCountDown.ts +10 -1
- package/components/composables/useDynamicVirtualScroll.ts +9 -0
- package/components/composables/useGlobalLoading.ts +6 -0
- package/components/composables/useGlobalMessage.ts +6 -0
- package/components/composables/useGlobalToast.ts +6 -0
- package/components/composables/useLockScroll.ts +9 -0
- package/components/composables/useParent.ts +65 -14
- package/components/composables/usePopover.ts +9 -0
- package/components/composables/useQueue.ts +8 -0
- package/components/composables/useRaf.ts +10 -0
- package/components/composables/useSharedState.ts +284 -0
- package/components/composables/useTouch.ts +8 -0
- package/components/composables/useTranslate.ts +9 -0
- package/components/composables/useUpload.ts +83 -11
- package/components/composables/useVirtualScroll.ts +7 -0
- package/components/composables/useWindowResize.ts +9 -0
- package/components/oxy-action-sheet/index.scss +5 -5
- package/components/oxy-action-sheet/oxy-action-sheet.vue +11 -0
- package/components/oxy-backtop/index.scss +2 -2
- package/components/oxy-backtop/oxy-backtop.vue +2 -0
- package/components/oxy-badge/oxy-badge.vue +2 -0
- package/components/oxy-badge/types.ts +3 -0
- package/components/oxy-button/index.scss +13 -13
- package/components/oxy-button/oxy-button.vue +11 -0
- package/components/oxy-button/types.ts +3 -3
- package/components/oxy-calendar/index.scss +17 -17
- package/components/oxy-calendar/oxy-calendar.vue +31 -0
- package/components/oxy-calendar/types.ts +3 -0
- package/components/oxy-calendar-view/month/month.vue +2 -0
- package/components/oxy-calendar-view/monthPanel/month-panel.vue +3 -1
- package/components/oxy-calendar-view/monthPanel/types.ts +10 -7
- package/components/oxy-calendar-view/oxy-calendar-view.vue +2 -0
- package/components/oxy-calendar-view/types.ts +3 -1
- package/components/oxy-calendar-view/year/types.ts +33 -1
- package/components/oxy-calendar-view/year/year.vue +2 -0
- package/components/oxy-calendar-view/yearPanel/year-panel.vue +2 -0
- package/components/oxy-card/index.scss +1 -1
- package/components/oxy-card/oxy-card.vue +2 -0
- package/components/oxy-cell/index.scss +3 -1
- package/components/oxy-cell/oxy-cell.vue +6 -4
- package/components/oxy-cell-group/oxy-cell-group.vue +2 -0
- package/components/oxy-checkbox/index.scss +7 -7
- package/components/oxy-checkbox/oxy-checkbox.vue +22 -16
- package/components/oxy-checkbox/types.ts +9 -0
- package/components/oxy-checkbox-group/index.scss +1 -1
- package/components/oxy-checkbox-group/oxy-checkbox-group.vue +2 -0
- package/components/oxy-circle/oxy-circle.vue +2 -0
- package/components/oxy-col/oxy-col.vue +3 -1
- package/components/oxy-col-picker/index.scss +3 -3
- package/components/oxy-col-picker/oxy-col-picker.vue +17 -1
- package/components/oxy-col-picker/types.ts +3 -0
- package/components/oxy-collapse/index.scss +2 -2
- package/components/oxy-collapse/oxy-collapse.vue +9 -0
- package/components/oxy-collapse-item/oxy-collapse-item.vue +4 -2
- package/components/oxy-config-provider/oxy-config-provider.vue +18 -0
- package/components/oxy-config-provider/types.ts +18 -0
- package/components/oxy-corner/index.scss +50 -32
- package/components/oxy-corner/oxy-corner.vue +2 -0
- package/components/oxy-count-down/oxy-count-down.vue +2 -0
- package/components/oxy-count-to/oxy-count-to.vue +12 -1
- package/components/oxy-count-to/types.ts +14 -4
- package/components/oxy-curtain/index.scss +10 -9
- package/components/oxy-curtain/oxy-curtain.vue +2 -0
- package/components/oxy-date-strip/oxy-date-strip.vue +22 -1
- package/components/oxy-date-strip-item/index.scss +4 -4
- package/components/oxy-date-strip-item/oxy-date-strip-item.vue +2 -0
- package/components/oxy-datetime-picker/index.scss +3 -3
- package/components/oxy-datetime-picker/oxy-datetime-picker.vue +11 -1
- package/components/oxy-datetime-picker-view/oxy-datetime-picker-view.vue +2 -0
- package/components/oxy-divider/oxy-divider.vue +2 -0
- package/components/oxy-drop-menu/index.scss +2 -2
- package/components/oxy-drop-menu/oxy-drop-menu.vue +3 -0
- package/components/oxy-drop-menu-item/index.scss +1 -1
- package/components/oxy-drop-menu-item/oxy-drop-menu-item.vue +17 -9
- package/components/oxy-echarts/oxy-echarts.vue +2 -0
- package/components/oxy-fab/index.scss +1 -1
- package/components/oxy-fab/oxy-fab.vue +27 -0
- package/components/oxy-file-list/index.scss +9 -9
- package/components/oxy-file-list/oxy-file-list.vue +29 -17
- package/components/oxy-floating-panel/oxy-floating-panel.vue +34 -10
- package/components/oxy-footer/index.scss +7 -0
- package/components/oxy-footer/oxy-footer.vue +4 -2
- package/components/oxy-footer/types.ts +9 -6
- package/components/oxy-form/oxy-form.vue +13 -1
- package/components/oxy-form-item/oxy-form-item.vue +5 -3
- package/components/oxy-gap/oxy-gap.vue +2 -0
- package/components/oxy-global-loading/oxy-global-loading.vue +18 -5
- package/components/oxy-global-message/oxy-global-message.vue +30 -17
- package/components/oxy-global-toast/oxy-global-toast.vue +18 -5
- package/components/oxy-grid/oxy-grid.vue +6 -0
- package/components/oxy-grid-item/index.scss +1 -1
- package/components/oxy-grid-item/oxy-grid-item.vue +22 -20
- package/components/oxy-guidance/index.scss +9 -9
- package/components/oxy-guidance/oxy-guidance.vue +22 -16
- package/components/oxy-icon/oxy-icon.vue +2 -0
- package/components/oxy-icon/types.ts +3 -0
- package/components/oxy-image-preview/index.scss +75 -0
- package/components/oxy-image-preview/index.ts +56 -0
- package/components/oxy-image-preview/oxy-image-preview.vue +221 -0
- package/components/oxy-image-preview/types.ts +164 -0
- package/components/oxy-img/oxy-img.vue +2 -0
- package/components/oxy-img-cropper/index.scss +2 -2
- package/components/oxy-img-cropper/oxy-img-cropper.vue +6 -0
- package/components/oxy-img-lazy/oxy-img-lazy.vue +9 -0
- package/components/oxy-index-anchor/index.scss +1 -1
- package/components/oxy-index-anchor/oxy-index-anchor.vue +2 -2
- package/components/oxy-index-bar/index.scss +1 -1
- package/components/oxy-index-bar/oxy-index-bar.vue +18 -0
- package/components/oxy-input/index.scss +2 -1
- package/components/oxy-input/oxy-input.vue +18 -4
- package/components/oxy-input/types.ts +6 -0
- package/components/oxy-input-number/index.scss +3 -1
- package/components/oxy-input-number/oxy-input-number.vue +2 -0
- package/components/oxy-keyboard/index.scss +3 -3
- package/components/oxy-keyboard/key/index.vue +2 -0
- package/components/oxy-keyboard/oxy-keyboard.vue +11 -2
- package/components/oxy-link/index.scss +8 -4
- package/components/oxy-link/oxy-link.vue +9 -3
- package/components/oxy-link/types.ts +2 -2
- package/components/oxy-list/oxy-list.vue +2 -0
- package/components/oxy-list/types.ts +7 -0
- package/components/oxy-loading/oxy-loading.vue +6 -0
- package/components/oxy-loadmore/index.scss +1 -1
- package/components/oxy-loadmore/oxy-loadmore.vue +2 -0
- package/components/oxy-long-press-menu/index.scss +1 -1
- package/components/oxy-long-press-menu/oxy-long-press-menu.vue +42 -13
- package/components/oxy-message-box/index.scss +223 -36
- package/components/oxy-message-box/index.ts +49 -23
- package/components/oxy-message-box/oxy-message-box.vue +181 -56
- package/components/oxy-message-box/types.ts +60 -2
- package/components/oxy-navbar/index.scss +1 -1
- package/components/oxy-navbar/oxy-navbar.vue +9 -6
- package/components/oxy-navbar-capsule/oxy-navbar-capsule.vue +2 -0
- package/components/oxy-notice-bar/index.scss +1 -1
- package/components/oxy-notice-bar/oxy-notice-bar.vue +29 -0
- package/components/oxy-notify/index.ts +16 -12
- package/components/oxy-notify/oxy-notify.vue +11 -4
- package/components/oxy-overlay/oxy-overlay.vue +34 -2
- package/components/oxy-pagination/oxy-pagination.vue +2 -0
- package/components/oxy-password-input/oxy-password-input.vue +2 -0
- package/components/oxy-picker/index.scss +7 -7
- package/components/oxy-picker/oxy-picker.vue +11 -0
- package/components/oxy-picker-view/index.scss +1 -1
- package/components/oxy-picker-view/oxy-picker-view.vue +2 -0
- package/components/oxy-popover/index.scss +2 -2
- package/components/oxy-popover/oxy-popover.vue +4 -1
- package/components/oxy-popup/oxy-popup.vue +8 -0
- package/components/oxy-progress/index.scss +2 -2
- package/components/oxy-progress/oxy-progress.vue +7 -0
- package/components/oxy-qrcode/draw.ts +15 -1
- package/components/oxy-qrcode/oxy-qrcode.vue +10 -3
- package/components/oxy-radio/index.scss +8 -8
- package/components/oxy-radio/oxy-radio.vue +13 -11
- package/components/oxy-radio-group/index.scss +1 -1
- package/components/oxy-radio-group/oxy-radio-group.vue +2 -0
- package/components/oxy-rate/oxy-rate.vue +5 -0
- package/components/oxy-rate/types.ts +2 -2
- package/components/oxy-resize/oxy-resize.vue +12 -0
- package/components/oxy-rich-text/index.scss +9 -9
- package/components/oxy-rich-text/oxy-rich-text.vue +6 -0
- package/components/oxy-rich-text/types.ts +15 -0
- package/components/oxy-root-portal/oxy-root-portal.vue +23 -15
- package/components/oxy-row/oxy-row.vue +2 -0
- package/components/oxy-search/index.scss +3 -3
- package/components/oxy-search/oxy-search.vue +19 -0
- package/components/oxy-segmented/index.scss +4 -4
- package/components/oxy-segmented/oxy-segmented.vue +2 -0
- package/components/oxy-select/index.scss +25 -25
- package/components/oxy-select/oxy-select.vue +27 -0
- package/components/oxy-select/types.ts +3 -0
- package/components/oxy-select-picker/index.scss +5 -5
- package/components/oxy-select-picker/oxy-select-picker.vue +7 -0
- package/components/oxy-sidebar/oxy-sidebar.vue +2 -0
- package/components/oxy-sidebar-item/index.scss +3 -3
- package/components/oxy-sidebar-item/oxy-sidebar-item.vue +17 -31
- package/components/oxy-signature/oxy-signature.vue +17 -0
- package/components/oxy-skeleton/oxy-skeleton.vue +7 -1
- package/components/oxy-slide-verify/index.scss +95 -0
- package/components/oxy-slide-verify/oxy-slide-verify.vue +244 -0
- package/components/oxy-slide-verify/types.ts +98 -0
- package/components/oxy-slider/oxy-slider.vue +3 -0
- package/components/oxy-sort-button/index.scss +10 -8
- package/components/oxy-sort-button/oxy-sort-button.vue +6 -0
- package/components/oxy-splitter/index.scss +9 -0
- package/components/oxy-splitter/oxy-splitter.vue +23 -2
- package/components/oxy-splitter-panel/index.scss +7 -5
- package/components/oxy-splitter-panel/oxy-splitter-panel.vue +93 -89
- package/components/oxy-status-tip/index.scss +3 -3
- package/components/oxy-status-tip/oxy-status-tip.vue +2 -0
- package/components/oxy-step/index.scss +4 -4
- package/components/oxy-step/oxy-step.vue +15 -13
- package/components/oxy-steps/oxy-steps.vue +2 -0
- package/components/oxy-sticky/oxy-sticky.vue +5 -3
- package/components/oxy-stream-render/oxy-stream-render.vue +29 -0
- package/components/oxy-swipe-action/oxy-swipe-action.vue +8 -0
- package/components/oxy-swiper/oxy-swiper.vue +6 -0
- package/components/oxy-swiper-nav/index.scss +4 -4
- package/components/oxy-switch/index.scss +6 -3
- package/components/oxy-switch/oxy-switch.vue +10 -0
- package/components/oxy-tab/index.scss +1 -7
- package/components/oxy-tab/oxy-tab.vue +12 -10
- package/components/oxy-tabbar/oxy-tabbar.vue +5 -0
- package/components/oxy-tabbar-item/oxy-tabbar-item.vue +11 -9
- package/components/oxy-table/index.scss +1 -1
- package/components/oxy-table/oxy-table.vue +8 -0
- package/components/oxy-table/types.ts +3 -0
- package/components/oxy-table-col/oxy-table-col.vue +21 -19
- package/components/oxy-tabs/index.scss +11 -11
- package/components/oxy-tabs/oxy-tabs.vue +17 -0
- package/components/oxy-tag/index.scss +24 -5
- package/components/oxy-tag/oxy-tag.vue +17 -2
- package/components/oxy-tag/types.ts +7 -0
- package/components/oxy-text/oxy-text.vue +12 -1
- package/components/oxy-textarea/index.scss +3 -2
- package/components/oxy-textarea/oxy-textarea.vue +10 -4
- package/components/oxy-toast/index.ts +21 -20
- package/components/oxy-toast/oxy-toast.vue +30 -5
- package/components/oxy-toast/types.ts +20 -9
- package/components/oxy-tooltip/index.scss +1 -1
- package/components/oxy-tooltip/oxy-tooltip.vue +2 -0
- package/components/oxy-transition/index.scss +3 -1
- package/components/oxy-transition/oxy-transition.vue +14 -0
- package/components/oxy-tree/index.scss +3 -3
- package/components/oxy-tree/oxy-tree.vue +28 -5
- package/components/oxy-tree/types.ts +57 -1
- package/components/oxy-upload/index.scss +9 -9
- package/components/oxy-upload/oxy-upload.vue +5 -3
- package/components/oxy-verification-code/oxy-verification-code.vue +24 -0
- package/components/oxy-video-preview/index.scss +12 -7
- package/components/oxy-video-preview/index.ts +64 -0
- package/components/oxy-video-preview/oxy-video-preview.vue +102 -31
- package/components/oxy-video-preview/types.ts +54 -8
- package/components/oxy-virtual-scroll/index.scss +1 -1
- package/components/oxy-virtual-scroll/oxy-virtual-scroll.vue +2 -0
- package/components/oxy-voice-player/index.scss +64 -64
- package/components/oxy-voice-player/oxy-voice-player.vue +38 -10
- package/components/oxy-waterfall/oxy-waterfall.vue +13 -0
- package/components/oxy-waterfall/types.ts +7 -0
- package/components/oxy-waterfall-item/oxy-waterfall-item.vue +9 -0
- package/components/oxy-watermark/oxy-watermark.vue +2 -0
- package/global.d.ts +2 -0
- package/index.ts +2 -0
- package/locale/lang/en-US.ts +51 -2
- package/locale/lang/zh-CN.ts +51 -2
- package/package.json +2 -2
- package/styles/all.scss +125 -0
- package/tags.json +1 -1
- package/vite-plugins/vite-plugin-host-class.ts +166 -0
- package/web-types.json +1 -1
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
import { ref, type Ref } from 'vue'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* 作用域解析器。
|
|
5
|
+
*
|
|
6
|
+
* 返回值用于隔离不同页面或不同运行上下文下的同名 selector。
|
|
7
|
+
* 默认实现会优先使用当前页面实例生成页面级 scope。
|
|
8
|
+
*/
|
|
9
|
+
type SharedStateScopeResolver = () => string
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* 状态 key 解析器。
|
|
13
|
+
*
|
|
14
|
+
* @param selector - 组件实例标识,例如 toast 的 selector。
|
|
15
|
+
* @param scopeId - 当前作用域标识,通常是页面级 scope。
|
|
16
|
+
* @returns 存入 stateMap 的最终 key。
|
|
17
|
+
*/
|
|
18
|
+
type SharedStateKeyResolver = (selector: string, scopeId: string) => string
|
|
19
|
+
|
|
20
|
+
type CreateSharedStateOptions = {
|
|
21
|
+
/**
|
|
22
|
+
* 状态命名空间。
|
|
23
|
+
*
|
|
24
|
+
* 同一个 namespace 会复用同一个全局状态 Map,不同 namespace 之间完全隔离。
|
|
25
|
+
* 例如 toast、message-box、notify 使用不同 namespace,避免默认 selector 相同时状态结构互相覆盖。
|
|
26
|
+
*/
|
|
27
|
+
namespace?: string
|
|
28
|
+
/**
|
|
29
|
+
* 自定义作用域解析逻辑。
|
|
30
|
+
*
|
|
31
|
+
* 未传入时默认使用当前页面实例生成页面级 scope,无法获取页面时退回 defaultScopeId。
|
|
32
|
+
*/
|
|
33
|
+
resolveScopeId?: SharedStateScopeResolver
|
|
34
|
+
/**
|
|
35
|
+
* 自定义最终状态 key 的生成逻辑。
|
|
36
|
+
*
|
|
37
|
+
* 未传入时默认使用 `${scopeId}_${selector}`;selector 为空时直接使用 scopeId。
|
|
38
|
+
*/
|
|
39
|
+
resolveKey?: SharedStateKeyResolver
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
type SharedStateStore = {
|
|
43
|
+
/**
|
|
44
|
+
* 全局 fallback scope 种子。
|
|
45
|
+
*
|
|
46
|
+
* 用于生成页面信息不可用时的默认 scope,放在全局 store 中可避免 H5 多份组件库实例各自计数。
|
|
47
|
+
*/
|
|
48
|
+
scopeSeed: number
|
|
49
|
+
/**
|
|
50
|
+
* 页面 scope 种子。
|
|
51
|
+
*
|
|
52
|
+
* 每遇到一个新的 uni-app 页面对象递增一次,用于生成稳定的页面级 scope。
|
|
53
|
+
*/
|
|
54
|
+
pageScopeSeed: number
|
|
55
|
+
/**
|
|
56
|
+
* 页面对象到页面 scope 的映射。
|
|
57
|
+
*
|
|
58
|
+
* 使用 WeakMap 可以让页面对象卸载后被正常回收,不需要手动删除历史页面记录。
|
|
59
|
+
*/
|
|
60
|
+
pageScopeMap: WeakMap<object, string>
|
|
61
|
+
/**
|
|
62
|
+
* namespace 到 fallback scope 的映射。
|
|
63
|
+
*
|
|
64
|
+
* 当 getCurrentPages 不可用时,同一个 namespace 仍能拿到稳定默认 scope,
|
|
65
|
+
* 保证 hook 侧和组件侧不会因为各自生成随机 scope 而读写不同状态。
|
|
66
|
+
*/
|
|
67
|
+
scopeIds: Map<string, string>
|
|
68
|
+
/**
|
|
69
|
+
* namespace 到状态 Map 的映射。
|
|
70
|
+
*
|
|
71
|
+
* 每个组件类型拥有独立状态容器,Map 内部再通过 scope + selector 区分具体实例。
|
|
72
|
+
*/
|
|
73
|
+
stateMaps: Map<string, Map<string, Ref<Record<string, any>>>>
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* 当前模块实例内的本地 store。
|
|
78
|
+
*
|
|
79
|
+
* 在不支持 globalThis 的运行环境中作为兜底;
|
|
80
|
+
* 正常情况下会挂到 globalThis,供可能存在的多份组件库代码共同复用。
|
|
81
|
+
*/
|
|
82
|
+
const localSharedStateStore: SharedStateStore = {
|
|
83
|
+
scopeSeed: 0,
|
|
84
|
+
pageScopeSeed: 0,
|
|
85
|
+
pageScopeMap: new WeakMap<object, string>(),
|
|
86
|
+
scopeIds: new Map(),
|
|
87
|
+
stateMaps: new Map()
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* 获取全局共享状态容器。
|
|
92
|
+
*
|
|
93
|
+
* 为什么放到 globalThis:
|
|
94
|
+
* - H5 或业务项目中可能同时存在组件库源码和打包产物,导致 useSharedState 模块被加载多份。
|
|
95
|
+
* - 如果每份模块都维护自己的 Map,`useToast()` 和 `<oxy-toast>` 可能读写到不同容器。
|
|
96
|
+
* - 挂到 globalThis 后,多份模块实例会落到同一个 store,从而保持状态一致。
|
|
97
|
+
*
|
|
98
|
+
* 如果当前运行环境没有可用的 globalThis,则退回模块内的 localSharedStateStore。
|
|
99
|
+
*/
|
|
100
|
+
function getSharedStateStore() {
|
|
101
|
+
const globalScope = typeof globalThis === 'object' ? (globalThis as Record<string, any>) : null
|
|
102
|
+
if (!globalScope) return localSharedStateStore
|
|
103
|
+
|
|
104
|
+
const storeKey = '__OXY_UNI_UI_SHARED_STATE__'
|
|
105
|
+
if (!globalScope[storeKey]) {
|
|
106
|
+
globalScope[storeKey] = localSharedStateStore
|
|
107
|
+
}
|
|
108
|
+
return globalScope[storeKey] as SharedStateStore
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* 创建一个随机 fallback scope。
|
|
113
|
+
*
|
|
114
|
+
* fallback scope 只用于无法解析当前页面的场景,例如:
|
|
115
|
+
* - getCurrentPages 不存在
|
|
116
|
+
* - getCurrentPages 返回空数组
|
|
117
|
+
* - 获取页面信息时出现异常
|
|
118
|
+
*
|
|
119
|
+
* 正常页面内调用时,会优先使用 createPageScopeId 生成页面级 scope。
|
|
120
|
+
*/
|
|
121
|
+
function createRandomScopeId() {
|
|
122
|
+
const store = getSharedStateStore()
|
|
123
|
+
store.scopeSeed += 1
|
|
124
|
+
return `shared_state_${Date.now()}_${Math.random().toString(36).slice(2, 10)}_${store.scopeSeed}`
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* 获取 namespace 对应的默认 fallback scope。
|
|
129
|
+
*
|
|
130
|
+
* 有 namespace 时,同一个组件类型复用同一个 fallback scope;
|
|
131
|
+
* 没有 namespace 时,每次 createSharedState 都生成独立 fallback scope,保持旧的隔离行为。
|
|
132
|
+
*/
|
|
133
|
+
function createDefaultScopeId(namespace?: string) {
|
|
134
|
+
if (!namespace) return createRandomScopeId()
|
|
135
|
+
|
|
136
|
+
const store = getSharedStateStore()
|
|
137
|
+
const scopeId = store.scopeIds.get(namespace)
|
|
138
|
+
if (scopeId) return scopeId
|
|
139
|
+
|
|
140
|
+
const newScopeId = createRandomScopeId()
|
|
141
|
+
store.scopeIds.set(namespace, newScopeId)
|
|
142
|
+
return newScopeId
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* 根据 uni-app 页面对象创建页面级 scope。
|
|
147
|
+
*
|
|
148
|
+
* 同一个页面对象会通过 WeakMap 复用同一个 scope;
|
|
149
|
+
* 不同页面对象即使 route 相同,也会分配不同 scope,避免 navigateTo 多次进入同一路由时状态串用。
|
|
150
|
+
*/
|
|
151
|
+
function createPageScopeId(page: object) {
|
|
152
|
+
const store = getSharedStateStore()
|
|
153
|
+
const scopeId = store.pageScopeMap.get(page)
|
|
154
|
+
if (scopeId) return scopeId
|
|
155
|
+
|
|
156
|
+
store.pageScopeSeed += 1
|
|
157
|
+
const route = 'route' in page && typeof page.route === 'string' ? page.route : 'unknown'
|
|
158
|
+
const pageScopeId = `shared_page_${route}_${store.pageScopeSeed}`
|
|
159
|
+
store.pageScopeMap.set(page, pageScopeId)
|
|
160
|
+
return pageScopeId
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* 获取 namespace 对应的状态 Map。
|
|
165
|
+
*
|
|
166
|
+
* 传入 namespace 时使用全局 store 中的共享 Map;
|
|
167
|
+
* 不传 namespace 时返回新的本地 Map,表示该 createSharedState 调用完全自持状态。
|
|
168
|
+
*/
|
|
169
|
+
function getStateMap<T extends Record<string, any>>(namespace?: string) {
|
|
170
|
+
if (!namespace) return new Map<string, Ref<T>>()
|
|
171
|
+
|
|
172
|
+
const store = getSharedStateStore()
|
|
173
|
+
const stateMap = store.stateMaps.get(namespace)
|
|
174
|
+
if (stateMap) return stateMap as Map<string, Ref<T>>
|
|
175
|
+
|
|
176
|
+
const newStateMap = new Map<string, Ref<T>>()
|
|
177
|
+
store.stateMaps.set(namespace, newStateMap as Map<string, Ref<Record<string, any>>>)
|
|
178
|
+
return newStateMap
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* 解析当前页面 scope。
|
|
183
|
+
*
|
|
184
|
+
* 正常情况下取页面栈最后一个页面作为当前页面,并为其生成页面级 scope。
|
|
185
|
+
* 任何平台 API 不存在或异常的情况都会回退到 defaultScopeId,保证调用方始终有可用 scope。
|
|
186
|
+
*/
|
|
187
|
+
function resolveCurrentPageScopeId(defaultScopeId: string) {
|
|
188
|
+
try {
|
|
189
|
+
if (typeof getCurrentPages !== 'function') return defaultScopeId
|
|
190
|
+
const pages = getCurrentPages()
|
|
191
|
+
const currentPage = pages[pages.length - 1]
|
|
192
|
+
return currentPage && typeof currentPage === 'object' ? createPageScopeId(currentPage) : defaultScopeId
|
|
193
|
+
} catch {
|
|
194
|
+
return defaultScopeId
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* 创建默认状态 key 解析器。
|
|
200
|
+
*
|
|
201
|
+
* 默认 key 由 scopeId 和 selector 拼接:
|
|
202
|
+
* - selector 为空:使用 scopeId,代表当前页面默认实例。
|
|
203
|
+
* - selector 非空:使用 `${scopeId}_${selector}`,代表当前页面指定实例。
|
|
204
|
+
*/
|
|
205
|
+
function createDefaultKeyResolver(resolveScopeId: SharedStateScopeResolver): SharedStateKeyResolver {
|
|
206
|
+
return (selector: string, scopeId: string) => {
|
|
207
|
+
const stableScopeId = scopeId || resolveScopeId()
|
|
208
|
+
return selector ? `${stableScopeId}_${selector}` : stableScopeId
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* 基于 Map 的模块级共享状态管理,用于替代 inject/provide 模式。
|
|
214
|
+
*
|
|
215
|
+
* 适用于 toast、message、notify 等需要基于 selector 多实例隔离的弹窗组件。
|
|
216
|
+
* 与 inject/provide 相比:
|
|
217
|
+
* - 不依赖组件树,可在任意位置(如 Pinia actions、工具函数)直接读写状态
|
|
218
|
+
* - 通过 selector 区分多实例,与原有 API 兼容
|
|
219
|
+
* - 提供显式清理方法,支持组件卸载时释放资源
|
|
220
|
+
*
|
|
221
|
+
* @param defaultFactory - 默认状态工厂函数,用于初始化新 selector 的状态
|
|
222
|
+
* @returns { getState, initState, removeState }
|
|
223
|
+
*
|
|
224
|
+
* @example
|
|
225
|
+
* ```ts
|
|
226
|
+
* const { initState, getState, removeState } = createSharedState(() => ({ show: false }))
|
|
227
|
+
*
|
|
228
|
+
* // 组件挂载时初始化
|
|
229
|
+
* const state = initState('mySelector')
|
|
230
|
+
*
|
|
231
|
+
* // 外部只读获取
|
|
232
|
+
* const current = getState('mySelector')
|
|
233
|
+
*
|
|
234
|
+
* // 组件卸载时清理
|
|
235
|
+
* onUnmounted(() => removeState('mySelector'))
|
|
236
|
+
* ```
|
|
237
|
+
*/
|
|
238
|
+
export function createSharedState<T extends Record<string, any>>(defaultFactory: () => T, options: CreateSharedStateOptions = {}) {
|
|
239
|
+
// 按 namespace 取得组件类型级别的状态容器,例如 toast 和 message-box 分属不同容器。
|
|
240
|
+
const stateMap = getStateMap<T>(options.namespace)
|
|
241
|
+
// 页面 scope 解析失败时使用的默认 scope;有 namespace 时同一组件类型保持稳定。
|
|
242
|
+
const defaultScopeId = createDefaultScopeId(options.namespace)
|
|
243
|
+
// 默认按当前页面对象生成 scope,确保不同页面的默认 selector 不会互相污染。
|
|
244
|
+
const resolveScopeId = options.resolveScopeId || (() => resolveCurrentPageScopeId(defaultScopeId))
|
|
245
|
+
// 默认按 scope + selector 生成最终状态 key,也允许调用方完全自定义。
|
|
246
|
+
const resolveKey = options.resolveKey || createDefaultKeyResolver(resolveScopeId)
|
|
247
|
+
// 统一收口 key 生成逻辑,保证 get/init/remove 使用完全一致的 key。
|
|
248
|
+
const resolveStateKey = (selector: string = '', scopeId: string = resolveScopeId()) => resolveKey(selector, scopeId)
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* 获取指定 selector 的共享状态(纯读,不存在返回 undefined)
|
|
252
|
+
* @param selector - 实例标识,空字符串表示默认实例
|
|
253
|
+
* @param scopeId - 指定作用域;不传时自动解析当前页面作用域
|
|
254
|
+
*/
|
|
255
|
+
const getState = (selector: string = '', scopeId: string = resolveScopeId()): Ref<T> | undefined => {
|
|
256
|
+
const key = resolveStateKey(selector, scopeId)
|
|
257
|
+
return stateMap.get(key)
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
* 初始化指定 selector 的共享状态(仅首次创建,已存在则复用)
|
|
262
|
+
* @param selector - 实例标识,空字符串表示默认实例
|
|
263
|
+
* @param scopeId - 指定作用域;不传时自动解析当前页面作用域
|
|
264
|
+
*/
|
|
265
|
+
const initState = (selector: string = '', scopeId: string = resolveScopeId()): Ref<T> => {
|
|
266
|
+
const key = resolveStateKey(selector, scopeId)
|
|
267
|
+
if (!stateMap.has(key)) {
|
|
268
|
+
stateMap.set(key, ref(defaultFactory()) as Ref<T>)
|
|
269
|
+
}
|
|
270
|
+
return stateMap.get(key)!
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
/**
|
|
274
|
+
* 移除指定 selector 的共享状态
|
|
275
|
+
* @param selector - 实例标识
|
|
276
|
+
* @param scopeId - 指定作用域;不传时自动解析当前页面作用域
|
|
277
|
+
*/
|
|
278
|
+
const removeState = (selector: string = '', scopeId: string = resolveScopeId()): void => {
|
|
279
|
+
const key = resolveStateKey(selector, scopeId)
|
|
280
|
+
stateMap.delete(key)
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
return { getState, initState, removeState, resolveScopeId, resolveStateKey }
|
|
284
|
+
}
|
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
import { ref } from 'vue'
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* 触摸事件处理 Hook,提供触摸方向、位移量的计算能力。
|
|
5
|
+
*
|
|
6
|
+
* 常用于滑动操作组件(如 swipe-action、slider、tabs),
|
|
7
|
+
* 通过 `touchStart` / `touchMove` 记录触摸位移,自动判断滑动方向。
|
|
8
|
+
*
|
|
9
|
+
* @returns 返回触摸状态、方向、位移量及事件处理方法。
|
|
10
|
+
*/
|
|
3
11
|
export function useTouch() {
|
|
4
12
|
const direction = ref<string>('')
|
|
5
13
|
const deltaX = ref<number>(0)
|
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
import { camelCase, getPropByPath, isDef, isFunction } from '../common/util'
|
|
2
2
|
import Locale from '../../locale'
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* 国际化翻译 Hook。
|
|
6
|
+
*
|
|
7
|
+
* 根据传入的组件名称读取 locale 模块中的翻译文案,
|
|
8
|
+
* 支持带参数的动态消息(如 `translate('weekFormat', year, week)`)。
|
|
9
|
+
*
|
|
10
|
+
* @param name 组件名称(驼峰),用作翻译 key 的前缀
|
|
11
|
+
* @returns `{ translate }` 翻译函数
|
|
12
|
+
*/
|
|
4
13
|
export const useTranslate = (name?: string) => {
|
|
5
14
|
const prefix = name ? camelCase(name) + '.' : ''
|
|
6
15
|
const translate = (key: string, ...args: unknown[]) => {
|
|
@@ -48,6 +48,11 @@ export interface UseUploadOptions {
|
|
|
48
48
|
extension?: string[]
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
+
/**
|
|
52
|
+
* 文件上传 Composable,封装了文件选择、上传任务管理、进度回调等能力
|
|
53
|
+
* 支持自定义上传方法、自动中断前一个上传任务
|
|
54
|
+
* @returns 包含 startUpload / abort / chooseFile / UPLOAD_STATUS 的返回对象
|
|
55
|
+
*/
|
|
51
56
|
export function useUpload(): UseUploadReturn {
|
|
52
57
|
let currentTask: UniApp.UploadTask | null = null
|
|
53
58
|
|
|
@@ -207,13 +212,16 @@ export function useUpload(): UseUploadReturn {
|
|
|
207
212
|
* 格式化媒体信息
|
|
208
213
|
*/
|
|
209
214
|
function formatMedia(res: UniApp.ChooseMediaSuccessCallbackResult): ChooseFile[] {
|
|
210
|
-
return res.tempFiles.map((item) =>
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
215
|
+
return res.tempFiles.map((item) => {
|
|
216
|
+
const mediaType = ((item as any).fileType || (item as any).mediaType || 'image') as 'image' | 'video'
|
|
217
|
+
return {
|
|
218
|
+
type: mediaType,
|
|
219
|
+
path: item.tempFilePath,
|
|
220
|
+
thumb: mediaType === 'video' ? item.thumbTempFilePath : item.tempFilePath,
|
|
221
|
+
size: item.size,
|
|
222
|
+
duration: item.duration
|
|
223
|
+
}
|
|
224
|
+
})
|
|
217
225
|
}
|
|
218
226
|
|
|
219
227
|
/**
|
|
@@ -258,7 +266,7 @@ export function useUpload(): UseUploadReturn {
|
|
|
258
266
|
// #endif
|
|
259
267
|
break
|
|
260
268
|
case 'video':
|
|
261
|
-
// #ifdef MP-WEIXIN
|
|
269
|
+
// #ifdef MP-WEIXIN || MP-TOUTIAO
|
|
262
270
|
uni.chooseMedia({
|
|
263
271
|
count: multiple ? maxCount : 1,
|
|
264
272
|
mediaType: ['video'],
|
|
@@ -269,7 +277,7 @@ export function useUpload(): UseUploadReturn {
|
|
|
269
277
|
fail: reject
|
|
270
278
|
})
|
|
271
279
|
// #endif
|
|
272
|
-
// #ifndef MP-WEIXIN
|
|
280
|
+
// #ifndef MP-WEIXIN || MP-TOUTIAO
|
|
273
281
|
uni.chooseVideo({
|
|
274
282
|
sourceType,
|
|
275
283
|
compressed,
|
|
@@ -283,10 +291,22 @@ export function useUpload(): UseUploadReturn {
|
|
|
283
291
|
})
|
|
284
292
|
// #endif
|
|
285
293
|
break
|
|
286
|
-
// #ifdef MP-WEIXIN
|
|
287
294
|
case 'media':
|
|
295
|
+
// #ifdef MP-WEIXIN
|
|
296
|
+
uni.chooseMedia({
|
|
297
|
+
count: multiple ? maxCount : 1,
|
|
298
|
+
sourceType,
|
|
299
|
+
sizeType,
|
|
300
|
+
camera,
|
|
301
|
+
maxDuration,
|
|
302
|
+
success: (res) => resolve(formatMedia(res)),
|
|
303
|
+
fail: reject
|
|
304
|
+
})
|
|
305
|
+
// #endif
|
|
306
|
+
// #ifdef MP-TOUTIAO
|
|
288
307
|
uni.chooseMedia({
|
|
289
308
|
count: multiple ? maxCount : 1,
|
|
309
|
+
mediaType: ['image', 'video'],
|
|
290
310
|
sourceType,
|
|
291
311
|
sizeType,
|
|
292
312
|
camera,
|
|
@@ -294,8 +314,22 @@ export function useUpload(): UseUploadReturn {
|
|
|
294
314
|
success: (res) => resolve(formatMedia(res)),
|
|
295
315
|
fail: reject
|
|
296
316
|
})
|
|
317
|
+
// #endif
|
|
318
|
+
// #ifndef MP-WEIXIN || MP-TOUTIAO
|
|
319
|
+
uni.chooseImage({
|
|
320
|
+
count: multiple ? maxCount : 1,
|
|
321
|
+
sizeType,
|
|
322
|
+
sourceType,
|
|
323
|
+
// #ifdef H5
|
|
324
|
+
extension,
|
|
325
|
+
// #endif
|
|
326
|
+
success: (res) => resolve(formatImage(res)),
|
|
327
|
+
fail: reject
|
|
328
|
+
})
|
|
329
|
+
// #endif
|
|
297
330
|
break
|
|
298
331
|
case 'file':
|
|
332
|
+
// #ifdef MP-WEIXIN
|
|
299
333
|
uni.chooseMessageFile({
|
|
300
334
|
count: multiple ? (isDef(maxCount) ? maxCount : 100) : 1,
|
|
301
335
|
type: accept,
|
|
@@ -303,8 +337,25 @@ export function useUpload(): UseUploadReturn {
|
|
|
303
337
|
success: (res) => resolve(res.tempFiles),
|
|
304
338
|
fail: reject
|
|
305
339
|
})
|
|
340
|
+
// #endif
|
|
341
|
+
// #ifdef MP-TOUTIAO
|
|
342
|
+
reject({
|
|
343
|
+
errMsg: 'chooseMessageFile is not supported in mp-toutiao'
|
|
344
|
+
})
|
|
345
|
+
// #endif
|
|
346
|
+
// #ifndef MP-WEIXIN || MP-TOUTIAO
|
|
347
|
+
uni.chooseImage({
|
|
348
|
+
count: multiple ? maxCount : 1,
|
|
349
|
+
sizeType,
|
|
350
|
+
sourceType,
|
|
351
|
+
// #ifdef H5
|
|
352
|
+
extension,
|
|
353
|
+
// #endif
|
|
354
|
+
success: (res) => resolve(formatImage(res)),
|
|
355
|
+
fail: reject
|
|
356
|
+
})
|
|
357
|
+
// #endif
|
|
306
358
|
break
|
|
307
|
-
// #endif
|
|
308
359
|
case 'all':
|
|
309
360
|
// #ifdef H5
|
|
310
361
|
uni.chooseFile({
|
|
@@ -324,6 +375,27 @@ export function useUpload(): UseUploadReturn {
|
|
|
324
375
|
fail: reject
|
|
325
376
|
})
|
|
326
377
|
// #endif
|
|
378
|
+
// #ifdef MP-TOUTIAO
|
|
379
|
+
uni.chooseMedia({
|
|
380
|
+
count: multiple ? maxCount : 1,
|
|
381
|
+
mediaType: ['image', 'video'],
|
|
382
|
+
sourceType,
|
|
383
|
+
sizeType,
|
|
384
|
+
camera,
|
|
385
|
+
maxDuration,
|
|
386
|
+
success: (res) => resolve(formatMedia(res)),
|
|
387
|
+
fail: reject
|
|
388
|
+
})
|
|
389
|
+
// #endif
|
|
390
|
+
// #ifndef H5 || MP-WEIXIN || MP-TOUTIAO
|
|
391
|
+
uni.chooseImage({
|
|
392
|
+
count: multiple ? maxCount : 1,
|
|
393
|
+
sizeType,
|
|
394
|
+
sourceType,
|
|
395
|
+
success: (res) => resolve(formatImage(res)),
|
|
396
|
+
fail: reject
|
|
397
|
+
})
|
|
398
|
+
// #endif
|
|
327
399
|
|
|
328
400
|
break
|
|
329
401
|
default:
|
|
@@ -37,6 +37,12 @@ export interface UseVirtualScrollReturn {
|
|
|
37
37
|
onScroll: (scrollTopValue: number) => void
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
+
/**
|
|
41
|
+
* 虚拟滚动 Composable,基于 VirtualScrollEngine 实现高性能长列表渲染
|
|
42
|
+
* 支持虚拟/非虚拟模式切换、滚动到指定位置/元素/ID
|
|
43
|
+
* @param options - 配置项,包含 data、virtual、height、itemHeight、idKey、backToTopThreshold
|
|
44
|
+
* @returns 滚动状态、可见数据及控制方法
|
|
45
|
+
*/
|
|
40
46
|
export function useVirtualScroll(options: UseVirtualScrollOptions): UseVirtualScrollReturn {
|
|
41
47
|
const { data, virtual, height, itemHeight, idKey, backToTopThreshold } = options
|
|
42
48
|
|
|
@@ -112,6 +118,7 @@ export function useVirtualScroll(options: UseVirtualScrollOptions): UseVirtualSc
|
|
|
112
118
|
}
|
|
113
119
|
}
|
|
114
120
|
|
|
121
|
+
/** 同步程序化滚动状态,更新内部滚动位置、回顶按钮显隐和可见数据 */
|
|
115
122
|
function syncProgrammaticScrollState(scrollTopValue: number) {
|
|
116
123
|
_scrollTop.value = scrollTopValue
|
|
117
124
|
showBackTopBtn.value = scrollTopValue > backToTopThresholdInPx.value
|
|
@@ -15,6 +15,15 @@ interface UseWindowResizeOptions {
|
|
|
15
15
|
immediate?: boolean
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
+
/**
|
|
19
|
+
* 监听窗口大小变化。
|
|
20
|
+
*
|
|
21
|
+
* 封装 `uni.onWindowResize` / `uni.offWindowResize`,
|
|
22
|
+
* 在组件挂载时注册监听,卸载时自动移除。
|
|
23
|
+
*
|
|
24
|
+
* @param callback 窗口大小变化时的回调
|
|
25
|
+
* @param options 配置项:`immediate` 是否立即调用一次回调
|
|
26
|
+
*/
|
|
18
27
|
export function useWindowResize(callback: WindowResizeCallback, options: UseWindowResizeOptions = {}) {
|
|
19
28
|
const { immediate = false } = options
|
|
20
29
|
|
|
@@ -62,7 +62,7 @@
|
|
|
62
62
|
margin-bottom: var(--window-bottom);
|
|
63
63
|
|
|
64
64
|
@include when(float) {
|
|
65
|
-
margin: 0
|
|
65
|
+
margin: 0 $-spacing-20 calc(var(--window-bottom) + $-spacing-20);
|
|
66
66
|
border-radius: $-action-sheet-radius;
|
|
67
67
|
overflow: hidden;
|
|
68
68
|
}
|
|
@@ -72,7 +72,7 @@
|
|
|
72
72
|
}
|
|
73
73
|
|
|
74
74
|
@include e(actions) {
|
|
75
|
-
padding:
|
|
75
|
+
padding: $-spacing-20 0;
|
|
76
76
|
max-height: 50vh;
|
|
77
77
|
overflow-y: auto;
|
|
78
78
|
-webkit-overflow-scrolling: touch;
|
|
@@ -123,7 +123,7 @@
|
|
|
123
123
|
|
|
124
124
|
@include e(subname) {
|
|
125
125
|
display: inline-block;
|
|
126
|
-
margin-left:
|
|
126
|
+
margin-left: $-spacing-12;
|
|
127
127
|
font-size: $-action-sheet-subname-fs;
|
|
128
128
|
color: $-action-sheet-subname-color;
|
|
129
129
|
}
|
|
@@ -140,7 +140,7 @@
|
|
|
140
140
|
border: none;
|
|
141
141
|
background: $-action-sheet-cancel-bg;
|
|
142
142
|
outline: none;
|
|
143
|
-
margin: 0 auto
|
|
143
|
+
margin: 0 auto $-spacing-48;
|
|
144
144
|
font-weight: $-action-sheet-weight;
|
|
145
145
|
|
|
146
146
|
&:active {
|
|
@@ -177,7 +177,7 @@
|
|
|
177
177
|
overflow-y: hidden;
|
|
178
178
|
|
|
179
179
|
&:first-of-type {
|
|
180
|
-
margin-top:
|
|
180
|
+
margin-top: $-spacing-40;
|
|
181
181
|
}
|
|
182
182
|
|
|
183
183
|
&:last-of-type {
|
|
@@ -59,7 +59,9 @@ export default {
|
|
|
59
59
|
name: 'oxy-action-sheet',
|
|
60
60
|
options: {
|
|
61
61
|
addGlobalClass: true,
|
|
62
|
+
// #ifndef MP-TOUTIAO
|
|
62
63
|
virtualHost: true,
|
|
64
|
+
// #endif
|
|
63
65
|
styleIsolation: 'shared'
|
|
64
66
|
}
|
|
65
67
|
}
|
|
@@ -105,6 +107,15 @@ function computedValue() {
|
|
|
105
107
|
formatPanels.value = isPanelArray() ? [props.panels as Panel[]] : (props.panels as Panel[][])
|
|
106
108
|
}
|
|
107
109
|
|
|
110
|
+
/**
|
|
111
|
+
* 选择操作项/面板项。
|
|
112
|
+
* action 模式:跳过 disabled/loading 项,emit select 事件。
|
|
113
|
+
* panels 模式:区分单层面板和嵌套面板,分别 emit 对应 index。
|
|
114
|
+
* 若 closeOnClickAction 为 true,选择后自动关闭。
|
|
115
|
+
* @param rowIndex - 行索引
|
|
116
|
+
* @param type - 选择类型('action' | 'panels')
|
|
117
|
+
* @param colIndex - 列索引(panels 模式)
|
|
118
|
+
*/
|
|
108
119
|
function select(rowIndex: number, type: 'action' | 'panels', colIndex?: number) {
|
|
109
120
|
if (type === 'action') {
|
|
110
121
|
if (props.actions[rowIndex].disabled || props.actions[rowIndex].loading) {
|