vue-stack-tabs 0.1.11 → 0.1.13

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 (72) hide show
  1. package/{types → dist}/src/lib/hooks/useStackTab.d.ts +2 -2
  2. package/{types → dist}/src/lib/hooks/useTabpanel.d.ts +6 -2
  3. package/{types → dist}/src/lib/index.d.ts +7 -1
  4. package/{types → dist}/src/lib/model/TabModel.d.ts +2 -1
  5. package/dist/style.css +1 -1
  6. package/dist/vue-stack-tabs.es.js +2340 -2321
  7. package/dist/vue-stack-tabs.umd.js +10 -10
  8. package/package.json +3 -4
  9. package/src/lib/StackTabs.vue +136 -126
  10. package/src/lib/assets/style/common/mixins.scss +45 -45
  11. package/src/lib/assets/style/common/var.scss +65 -65
  12. package/src/lib/assets/style/icon.scss +93 -93
  13. package/src/lib/assets/style/index.scss +4 -4
  14. package/src/lib/assets/style/overlayer.scss +40 -40
  15. package/src/lib/assets/style/stackTab.scss +395 -395
  16. package/src/lib/assets/style/transition.scss +40 -40
  17. package/src/lib/banner.ts +51 -51
  18. package/src/lib/components/ContextMenu/ContextMenuItem.vue +15 -15
  19. package/src/lib/components/ContextMenu/index.vue +129 -129
  20. package/src/lib/components/OverlayLoading/Component.vue +182 -191
  21. package/src/lib/components/OverlayLoading/api.ts +31 -31
  22. package/src/lib/components/OverlayLoading/helpers.ts +31 -31
  23. package/src/lib/components/OverlayLoading/index.ts +12 -12
  24. package/src/lib/components/OverlayLoading/loaders/bars.vue +79 -79
  25. package/src/lib/components/OverlayLoading/loaders/dots.vue +92 -92
  26. package/src/lib/components/OverlayLoading/loaders/index.ts +9 -9
  27. package/src/lib/components/OverlayLoading/loaders/spinner.vue +41 -41
  28. package/src/lib/components/TabHeader/TabHeaderButton.vue +35 -35
  29. package/src/lib/components/TabHeader/TabHeaderItem.vue +63 -63
  30. package/src/lib/components/TabHeader/TabHeaderScroll.vue +240 -240
  31. package/src/lib/components/TabHeader/index.vue +135 -135
  32. package/src/lib/hooks/useContextMenu.ts +50 -50
  33. package/src/lib/hooks/useStackTab.ts +74 -65
  34. package/src/lib/hooks/useTabLoading.ts +34 -34
  35. package/src/lib/hooks/useTabRouter.ts +94 -94
  36. package/src/lib/hooks/useTabpanel.tsx +516 -491
  37. package/src/lib/i18n/index.ts +72 -72
  38. package/src/lib/i18n/lang/en.ts +15 -15
  39. package/src/lib/i18n/lang/zh-CN.ts +15 -15
  40. package/src/lib/iframe.vue +7 -7
  41. package/src/lib/index.ts +32 -23
  42. package/src/lib/model/TabModel.ts +178 -169
  43. package/src/lib/utils/TabIdHelper.ts +70 -70
  44. package/src/lib/utils/TabScrollHelper.ts +104 -104
  45. package/src/lib/utils/UriHelper.ts +22 -22
  46. /package/{types → dist}/index.d.ts +0 -0
  47. /package/{types → dist}/src/lib/StackTabs.vue.d.ts +0 -0
  48. /package/{types → dist}/src/lib/banner.d.ts +0 -0
  49. /package/{types → dist}/src/lib/components/ContextMenu/ContextMenuItem.vue.d.ts +0 -0
  50. /package/{types → dist}/src/lib/components/ContextMenu/index.vue.d.ts +0 -0
  51. /package/{types → dist}/src/lib/components/OverlayLoading/Component.vue.d.ts +0 -0
  52. /package/{types → dist}/src/lib/components/OverlayLoading/api.d.ts +0 -0
  53. /package/{types → dist}/src/lib/components/OverlayLoading/helpers.d.ts +0 -0
  54. /package/{types → dist}/src/lib/components/OverlayLoading/index.d.ts +0 -0
  55. /package/{types → dist}/src/lib/components/OverlayLoading/loaders/bars.vue.d.ts +0 -0
  56. /package/{types → dist}/src/lib/components/OverlayLoading/loaders/dots.vue.d.ts +0 -0
  57. /package/{types → dist}/src/lib/components/OverlayLoading/loaders/index.d.ts +0 -0
  58. /package/{types → dist}/src/lib/components/OverlayLoading/loaders/spinner.vue.d.ts +0 -0
  59. /package/{types → dist}/src/lib/components/TabHeader/TabHeaderButton.vue.d.ts +0 -0
  60. /package/{types → dist}/src/lib/components/TabHeader/TabHeaderItem.vue.d.ts +0 -0
  61. /package/{types → dist}/src/lib/components/TabHeader/TabHeaderScroll.vue.d.ts +0 -0
  62. /package/{types → dist}/src/lib/components/TabHeader/index.vue.d.ts +0 -0
  63. /package/{types → dist}/src/lib/hooks/useContextMenu.d.ts +0 -0
  64. /package/{types → dist}/src/lib/hooks/useTabLoading.d.ts +0 -0
  65. /package/{types → dist}/src/lib/hooks/useTabRouter.d.ts +0 -0
  66. /package/{types → dist}/src/lib/i18n/index.d.ts +0 -0
  67. /package/{types → dist}/src/lib/i18n/lang/en.d.ts +0 -0
  68. /package/{types → dist}/src/lib/i18n/lang/zh-CN.d.ts +0 -0
  69. /package/{types → dist}/src/lib/iframe.vue.d.ts +0 -0
  70. /package/{types → dist}/src/lib/utils/TabIdHelper.d.ts +0 -0
  71. /package/{types → dist}/src/lib/utils/TabScrollHelper.d.ts +0 -0
  72. /package/{types → dist}/src/lib/utils/UriHelper.d.ts +0 -0
@@ -1,135 +1,135 @@
1
- <template>
2
- <div class="stack-tab__header">
3
- <slot name="leftButton" />
4
- <tab-header-scroll
5
- ref="scroll"
6
- :space="space"
7
- :is-scroll-wheel="isScrollWheel"
8
- :is-scroll-button="isScrollButton"
9
- >
10
- <template #default>
11
- <transition-group
12
- key="tabItemTrans"
13
- tag="ul"
14
- class="stack-tab__nav"
15
- v-bind="tabTrans"
16
- appear
17
- >
18
- <tab-header-item
19
- v-for="(item, index) in tabs"
20
- :key="item.id"
21
- :contextmenu="contextmenu"
22
- :item="item"
23
- @contextmenu.prevent="
24
- (e: MouseEvent) => showContextMenu(e, item as ITabItem, index, tabs.length)
25
- "
26
- @click.middle.prevent="closeTab(item as ITabItem)"
27
- @close="closeTab"
28
- @active="activeTab"
29
- />
30
- </transition-group>
31
- </template>
32
- </tab-header-scroll>
33
- <slot name="rightButton" />
34
- <tab-header-button
35
- :icon-class="maximum ? 'stack-tab__icon-restore' : 'stack-tab__icon-fullscreen'"
36
- :title="t('VueStackTab.maximum')"
37
- @click="maximum = !maximum"
38
- />
39
- <transition name="stack-tab-zoom" appear>
40
- <context-menu
41
- v-if="contextMenuShown"
42
- key="tabMenuTrans"
43
- :left="contextMenuData.left"
44
- :top="contextMenuData.top"
45
- :tab-item="contextMenuData.item as ITabItem"
46
- :max="contextMenuData.max"
47
- :index="contextMenuData.index"
48
- />
49
- </transition>
50
- </div>
51
- </template>
52
-
53
- <script lang="ts" setup>
54
- // @ts-nocheck
55
- import { inject, computed, ref } from 'vue'
56
- import type { TransitionProps, Ref } from 'vue'
57
- import { TabScrollMode } from '../../model/TabModel'
58
- import type { ITabItem } from '../../model/TabModel'
59
- import ContextMenu from '../ContextMenu/index.vue'
60
- import useContextMenu from '../../hooks/useContextMenu'
61
- import localeI18n from '../../i18n'
62
- import useTabpanel from '../../hooks/useTabpanel'
63
- import TabHeaderItem from './TabHeaderItem.vue'
64
- import TabHeaderScroll from './TabHeaderScroll.vue'
65
- import TabHeaderButton from './TabHeaderButton.vue'
66
- // @ts-ignore
67
- const { t } = localeI18n().getI18n()
68
- const maximum = inject<boolean>('maximum')
69
- const emit = defineEmits(['active'])
70
- const scroll = ref()
71
- const { shown: contextMenuShown, contextMenuData, showContextMenu } = useContextMenu()
72
-
73
- const props = withDefaults(
74
- defineProps<{
75
- space: number
76
- // tab的滚动方式
77
- tabScrollMode?: TabScrollMode
78
- // tab动画
79
- tabTransition?: string | TransitionProps
80
- contextmenu?: boolean | object
81
- max?: number
82
- }>(),
83
- {
84
- tabTransition: () => {
85
- return {
86
- name: 'stack-tab-zoom'
87
- }
88
- },
89
- tabScrollMode: TabScrollMode.BOTH,
90
- contextmenu: true,
91
- max: 20
92
- }
93
- )
94
- const { removeTab, active, tabs } = useTabpanel()
95
-
96
- // 转换tab动画
97
- const tabTrans = computed<TransitionProps>(() => {
98
- if (typeof props.tabTransition === 'string') {
99
- return {
100
- name: props.tabTransition
101
- } as TransitionProps
102
- }
103
- return props.tabTransition as TransitionProps
104
- })
105
- // 判断是否有滚动按钮
106
- const isScrollButton = computed<boolean>(() => {
107
- return props.tabScrollMode === TabScrollMode.BOTH || props.tabScrollMode === TabScrollMode.BUTTON
108
- })
109
- // 判断是否可以使用滚轮
110
- const isScrollWheel =
111
- props.tabScrollMode === TabScrollMode.BOTH || props.tabScrollMode === TabScrollMode.WHEEL
112
-
113
- // 关闭前,先判断是不最先中状态
114
- const closeTab = (item: ITabItem) => {
115
- // emit('close', item)
116
- if (item.closable) {
117
- const activeId = removeTab(item.id)
118
- emit('active', activeId)
119
- }
120
- contextMenuShown.value = false
121
- }
122
-
123
- const activeTab = (item: ITabItem, curActiveTab: Ref<HTMLElement>) => {
124
- if (scroll.value) {
125
- if (!scroll.value!.isInView(curActiveTab.value)) {
126
- scroll.value!.scrollIntoView(curActiveTab.value)
127
- }
128
-
129
- active(item.id)
130
- emit('active', item.id)
131
- }
132
- }
133
- </script>
134
-
135
- <style scoped></style>
1
+ <template>
2
+ <div class="stack-tab__header">
3
+ <slot name="leftButton" />
4
+ <tab-header-scroll
5
+ ref="scroll"
6
+ :space="space"
7
+ :is-scroll-wheel="isScrollWheel"
8
+ :is-scroll-button="isScrollButton"
9
+ >
10
+ <template #default>
11
+ <transition-group
12
+ key="tabItemTrans"
13
+ tag="ul"
14
+ class="stack-tab__nav"
15
+ v-bind="tabTrans"
16
+ appear
17
+ >
18
+ <tab-header-item
19
+ v-for="(item, index) in tabs"
20
+ :key="item.id"
21
+ :contextmenu="contextmenu"
22
+ :item="item"
23
+ @contextmenu.prevent="
24
+ (e: MouseEvent) => showContextMenu(e, item as ITabItem, index, tabs.length)
25
+ "
26
+ @click.middle.prevent="closeTab(item as ITabItem)"
27
+ @close="closeTab"
28
+ @active="activeTab"
29
+ />
30
+ </transition-group>
31
+ </template>
32
+ </tab-header-scroll>
33
+ <slot name="rightButton" />
34
+ <tab-header-button
35
+ :icon-class="maximum ? 'stack-tab__icon-restore' : 'stack-tab__icon-fullscreen'"
36
+ :title="t('VueStackTab.maximum')"
37
+ @click="maximum = !maximum"
38
+ />
39
+ <transition name="stack-tab-zoom" appear>
40
+ <context-menu
41
+ v-if="contextMenuShown"
42
+ key="tabMenuTrans"
43
+ :left="contextMenuData.left"
44
+ :top="contextMenuData.top"
45
+ :tab-item="contextMenuData.item as ITabItem"
46
+ :max="contextMenuData.max"
47
+ :index="contextMenuData.index"
48
+ />
49
+ </transition>
50
+ </div>
51
+ </template>
52
+
53
+ <script lang="ts" setup>
54
+ // @ts-nocheck
55
+ import { inject, computed, ref } from 'vue'
56
+ import type { TransitionProps, Ref } from 'vue'
57
+ import { TabScrollMode } from '../../model/TabModel'
58
+ import type { ITabItem } from '../../model/TabModel'
59
+ import ContextMenu from '../ContextMenu/index.vue'
60
+ import useContextMenu from '../../hooks/useContextMenu'
61
+ import localeI18n from '../../i18n'
62
+ import useTabpanel from '../../hooks/useTabpanel'
63
+ import TabHeaderItem from './TabHeaderItem.vue'
64
+ import TabHeaderScroll from './TabHeaderScroll.vue'
65
+ import TabHeaderButton from './TabHeaderButton.vue'
66
+ // @ts-ignore
67
+ const { t } = localeI18n().getI18n()
68
+ const maximum = inject<boolean>('maximum')
69
+ const emit = defineEmits(['active'])
70
+ const scroll = ref()
71
+ const { shown: contextMenuShown, contextMenuData, showContextMenu } = useContextMenu()
72
+
73
+ const props = withDefaults(
74
+ defineProps<{
75
+ space: number
76
+ // tab的滚动方式
77
+ tabScrollMode?: TabScrollMode
78
+ // tab动画
79
+ tabTransition?: string | TransitionProps
80
+ contextmenu?: boolean | object
81
+ max?: number
82
+ }>(),
83
+ {
84
+ tabTransition: () => {
85
+ return {
86
+ name: 'stack-tab-zoom'
87
+ }
88
+ },
89
+ tabScrollMode: TabScrollMode.BOTH,
90
+ contextmenu: true,
91
+ max: 20
92
+ }
93
+ )
94
+ const { removeTab, active, tabs } = useTabpanel()
95
+
96
+ // 转换tab动画
97
+ const tabTrans = computed<TransitionProps>(() => {
98
+ if (typeof props.tabTransition === 'string') {
99
+ return {
100
+ name: props.tabTransition
101
+ } as TransitionProps
102
+ }
103
+ return props.tabTransition as TransitionProps
104
+ })
105
+ // 判断是否有滚动按钮
106
+ const isScrollButton = computed<boolean>(() => {
107
+ return props.tabScrollMode === TabScrollMode.BOTH || props.tabScrollMode === TabScrollMode.BUTTON
108
+ })
109
+ // 判断是否可以使用滚轮
110
+ const isScrollWheel =
111
+ props.tabScrollMode === TabScrollMode.BOTH || props.tabScrollMode === TabScrollMode.WHEEL
112
+
113
+ // 关闭前,先判断是不最先中状态
114
+ const closeTab = (item: ITabItem) => {
115
+ // emit('close', item)
116
+ if (item.closable) {
117
+ const activeId = removeTab(item.id)
118
+ emit('active', activeId)
119
+ }
120
+ contextMenuShown.value = false
121
+ }
122
+
123
+ const activeTab = (item: ITabItem, curActiveTab: Ref<HTMLElement>) => {
124
+ if (scroll.value) {
125
+ if (!scroll.value!.isInView(curActiveTab.value)) {
126
+ scroll.value!.scrollIntoView(curActiveTab.value)
127
+ }
128
+
129
+ active(item.id)
130
+ emit('active', item.id)
131
+ }
132
+ }
133
+ </script>
134
+
135
+ <style scoped></style>
@@ -1,50 +1,50 @@
1
- import { onUnmounted, onMounted, ref, reactive, nextTick } from 'vue'
2
- import type { ITabItem } from '../model/TabModel'
3
- export default () => {
4
- const contextMenuData = reactive({
5
- item: {},
6
- index: -1,
7
- left: 0,
8
- top: 0,
9
- max: 0
10
- })
11
- const shown = ref<boolean>(false)
12
-
13
- onMounted(() => {
14
- document.addEventListener('click', clickOutSide)
15
- })
16
- onUnmounted(() => {
17
- document.removeEventListener('click', clickOutSide)
18
- })
19
-
20
- const showContextMenu = async (e: MouseEvent, item: ITabItem, index: number, max: number) => {
21
- // 关闭已打开的菜单
22
- shown.value = false
23
-
24
- await nextTick(() => {
25
- const { clientY: top, clientX: left } = e
26
- shown.value = true
27
- Object.assign(contextMenuData, { item, index, top, left, max })
28
-
29
- console.log('showContextMenu in callback')
30
- })
31
-
32
- // .then(() => {
33
-
34
- // })
35
- }
36
-
37
- const clickOutSide = (ev: MouseEvent) => {
38
- const classList = (ev.target as Element).classList
39
- if (classList.contains('stack-tab__contextmenu')) {
40
- return
41
- }
42
- shown.value = false
43
- }
44
-
45
- return {
46
- shown,
47
- contextMenuData,
48
- showContextMenu
49
- }
50
- }
1
+ import { onUnmounted, onMounted, ref, reactive, nextTick } from 'vue'
2
+ import type { ITabItem } from '../model/TabModel'
3
+ export default () => {
4
+ const contextMenuData = reactive({
5
+ item: {},
6
+ index: -1,
7
+ left: 0,
8
+ top: 0,
9
+ max: 0
10
+ })
11
+ const shown = ref<boolean>(false)
12
+
13
+ onMounted(() => {
14
+ document.addEventListener('click', clickOutSide)
15
+ })
16
+ onUnmounted(() => {
17
+ document.removeEventListener('click', clickOutSide)
18
+ })
19
+
20
+ const showContextMenu = async (e: MouseEvent, item: ITabItem, index: number, max: number) => {
21
+ // 关闭已打开的菜单
22
+ shown.value = false
23
+
24
+ await nextTick(() => {
25
+ const { clientY: top, clientX: left } = e
26
+ shown.value = true
27
+ Object.assign(contextMenuData, { item, index, top, left, max })
28
+
29
+ console.log('showContextMenu in callback')
30
+ })
31
+
32
+ // .then(() => {
33
+
34
+ // })
35
+ }
36
+
37
+ const clickOutSide = (ev: MouseEvent) => {
38
+ const classList = (ev.target as Element).classList
39
+ if (classList.contains('stack-tab__contextmenu')) {
40
+ return
41
+ }
42
+ shown.value = false
43
+ }
44
+
45
+ return {
46
+ shown,
47
+ contextMenuData,
48
+ showContextMenu
49
+ }
50
+ }
@@ -1,65 +1,74 @@
1
- import { useRouter } from 'vue-router'
2
- import useTabpanel from '../hooks/useTabpanel'
3
- import { throttle } from 'lodash-es'
4
- import type { ITabData } from '../model/TabModel'
5
- import { defu } from 'defu'
6
- import { encodeTabInfo } from '../utils/TabIdHelper'
7
- import { uriDecode } from '../utils/UriHelper'
8
- import { ulid } from 'ulidx'
9
- let iframePath: string
10
- export default () => {
11
- const router = useRouter()
12
- const { active, hasTab, pageShown, reset } = useTabpanel()
13
-
14
- /**
15
- * 打开新的TAB页面
16
- * @param tab
17
- * @param to
18
- */
19
- const openNewTab = throttle(async (tab: ITabData) => {
20
- if (!pageShown.value) {
21
- return
22
- }
23
- const tabInfo = defu(tab, { refreshable: true, closable: true, iframe: false })
24
-
25
- /**
26
- * In the function of openNewTab, if the tab already 'ACTIVE' then do nothing.
27
- */
28
- if (hasTab(tabInfo.id!)) {
29
- active(tabInfo.id!)
30
- return
31
- }
32
- if (!tabInfo.id) {
33
- tabInfo.id = ulid()
34
- }
35
- const __tab = encodeTabInfo(tabInfo)
36
- let query = defu(
37
- {
38
- __tab
39
- },
40
- tab.query
41
- ) as Record<string, string>
42
- let path
43
- if (!tab.iframe) {
44
- const url = uriDecode(tab.path)
45
- path = url.path
46
- query = defu(url.query, query)
47
- } else {
48
- const __src = encodeURIComponent(tab.path as string)
49
- path = iframePath
50
- query['__src'] = __src
51
- }
52
-
53
- router.push({
54
- path,
55
- query
56
- })
57
- return tabInfo.id
58
- }, 500)
59
-
60
- const setIFramePath = (path: string) => {
61
- iframePath = path
62
- }
63
-
64
- return { openNewTab, setIFramePath, active, reset }
65
- }
1
+ import { useRouter } from 'vue-router'
2
+ import useTabpanel from '../hooks/useTabpanel'
3
+ import { throttle } from 'lodash-es'
4
+ import type { ITabData } from '../model/TabModel'
5
+ import { defu } from 'defu'
6
+ import { encodeTabInfo } from '../utils/TabIdHelper'
7
+ import { uriDecode } from '../utils/UriHelper'
8
+ import { ulid } from 'ulidx'
9
+ let iframePath: string
10
+ export default () => {
11
+ const router = useRouter()
12
+ const { active, hasTab, pageShown, reset,canAddTab } = useTabpanel()
13
+
14
+ /**
15
+ * 打开新的TAB页面
16
+ * @param tab
17
+ * @param to
18
+ */
19
+ const openNewTab = throttle((tab: ITabData) => {
20
+ return new Promise((resolve, reject)=>{
21
+ if(!canAddTab()){
22
+ reject()
23
+ return
24
+ }
25
+ if (!pageShown.value) {
26
+ reject()
27
+ return
28
+ }
29
+ const tabInfo = defu(tab, { refreshable: true, closable: true, iframe: false })
30
+
31
+ /**
32
+ * In the function of openNewTab, if the tab already 'ACTIVE' then do nothing.
33
+ */
34
+ if (hasTab(tabInfo.id!)) {
35
+ active(tabInfo.id!)
36
+ resolve(tabInfo.id)
37
+ return
38
+ }
39
+ if (!tabInfo.id) {
40
+ tabInfo.id = ulid()
41
+ }
42
+ const __tab = encodeTabInfo(tabInfo)
43
+ let query = defu(
44
+ {
45
+ __tab
46
+ },
47
+ tab.query
48
+ ) as Record<string, string>
49
+ let path
50
+ if (!tab.iframe) {
51
+ const url = uriDecode(tab.path)
52
+ path = url.path
53
+ query = defu(url.query, query)
54
+ } else {
55
+ const __src = encodeURIComponent(tab.path as string)
56
+ path = iframePath
57
+ query['__src'] = __src
58
+ }
59
+
60
+ router.push({
61
+ path,
62
+ query
63
+ })
64
+ resolve(tabInfo.id)
65
+ })
66
+
67
+ }, 500)
68
+
69
+ const setIFramePath = (path: string) => {
70
+ iframePath = path
71
+ }
72
+
73
+ return { openNewTab, setIFramePath, active, reset }
74
+ }
@@ -1,34 +1,34 @@
1
- import { useLoading } from '../components/OverlayLoading'
2
- import { type ComponentInternalInstance, getCurrentInstance, onUnmounted } from 'vue'
3
-
4
- export default () => {
5
- const $loading = useLoading()
6
- const { attrs } = getCurrentInstance() as ComponentInternalInstance
7
- let loadingInstance: any | null = null
8
- onUnmounted(() => {
9
- closeTabLoading()
10
- })
11
- const openTabLoading = () => {
12
- const container = document.querySelector(`#${attrs.tId}`)
13
- if (loadingInstance === null) {
14
- loadingInstance = $loading.show({
15
- canCancel: false,
16
- isFullPage: false,
17
- height: 85,
18
- width: 85,
19
- loader: 'spinner',
20
- color: '#007bff',
21
-
22
- container: container!
23
- })
24
- }
25
- }
26
-
27
- const closeTabLoading = () => {
28
- if (loadingInstance !== null) {
29
- loadingInstance.hide()
30
- loadingInstance = null
31
- }
32
- }
33
- return { openTabLoading, closeTabLoading }
34
- }
1
+ import { useLoading } from '../components/OverlayLoading'
2
+ import { type ComponentInternalInstance, getCurrentInstance, onUnmounted } from 'vue'
3
+
4
+ export default () => {
5
+ const $loading = useLoading()
6
+ const { attrs } = getCurrentInstance() as ComponentInternalInstance
7
+ let loadingInstance: any | null = null
8
+ onUnmounted(() => {
9
+ closeTabLoading()
10
+ })
11
+ const openTabLoading = () => {
12
+ const container = document.querySelector(`#${attrs.tId}`)
13
+ if (loadingInstance === null) {
14
+ loadingInstance = $loading.show({
15
+ canCancel: false,
16
+ isFullPage: false,
17
+ height: 85,
18
+ width: 85,
19
+ loader: 'spinner',
20
+ color: '#007bff',
21
+
22
+ container: container!
23
+ })
24
+ }
25
+ }
26
+
27
+ const closeTabLoading = () => {
28
+ if (loadingInstance !== null) {
29
+ loadingInstance.hide()
30
+ loadingInstance = null
31
+ }
32
+ }
33
+ return { openTabLoading, closeTabLoading }
34
+ }