bge-ui 1.9.0 → 1.9.2

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/dist/index.js CHANGED
@@ -4,7 +4,7 @@ var __publicField = (obj, key, value) => {
4
4
  __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
5
5
  return value;
6
6
  };
7
- import { defineComponent, resolveComponent, openBlock, createElementBlock, normalizeClass, createElementVNode, createVNode, renderSlot, normalizeStyle, createStaticVNode, provide, reactive, toRefs, ref, watch, getCurrentScope, onScopeDispose, unref, readonly, computed, getCurrentInstance, onMounted, useSlots, inject, createTextVNode, toDisplayString, createCommentVNode, TransitionGroup, withCtx, nextTick, createBlock, withModifiers, withDirectives, cloneVNode, Fragment, Text, Comment, onUnmounted, h, Transition, vShow, onBeforeMount, Teleport, resolveDynamicComponent, shallowReactive, render as render$7, isVNode, vModelCheckbox, renderList, toRef, useAttrs, normalizeProps, mergeProps, onBeforeUpdate, withKeys, createSlots, guardReactiveProps, isRef } from "vue";
7
+ import { defineComponent, resolveComponent, openBlock, createElementBlock, normalizeClass, createElementVNode, createVNode, renderSlot, normalizeStyle, createStaticVNode, provide, reactive, toRefs, ref, watch, getCurrentScope, onScopeDispose, unref, readonly, computed, getCurrentInstance, onMounted, useSlots, inject, createTextVNode, toDisplayString, createCommentVNode, TransitionGroup, withCtx, nextTick, createBlock, withModifiers, onUnmounted, withDirectives, cloneVNode, Fragment, Text, Comment, h, Transition, vShow, onBeforeMount, Teleport, resolveDynamicComponent, shallowReactive, render as render$7, isVNode, vModelCheckbox, renderList, toRef, useAttrs, normalizeProps, mergeProps, onBeforeUpdate, withKeys, createSlots, guardReactiveProps, isRef } from "vue";
8
8
  const _hoisted_1$2d = ["disabled"];
9
9
  const _hoisted_2$1U = { class: "loading-icon" };
10
10
  const _sfc_main$2o = /* @__PURE__ */ defineComponent({
@@ -6648,6 +6648,7 @@ const _sfc_main$v = /* @__PURE__ */ defineComponent({
6648
6648
  };
6649
6649
  }
6650
6650
  });
6651
+ const maxRetryCount = 3;
6651
6652
  const tabsKey$1 = "bge-tabs-context";
6652
6653
  const _sfc_main$u = /* @__PURE__ */ defineComponent({
6653
6654
  ...{
@@ -6679,10 +6680,27 @@ const _sfc_main$u = /* @__PURE__ */ defineComponent({
6679
6680
  const barStyle = ref();
6680
6681
  const navOffset = ref(0);
6681
6682
  const scrollable = ref(false);
6683
+ const updateRetryCount = ref(0);
6682
6684
  const tabsRef = ref(null);
6683
6685
  const navScrollRef = ref(null);
6684
6686
  function addPane(pane) {
6685
- panes.value.push(pane);
6687
+ const existingIndex = panes.value.findIndex(
6688
+ (p) => p.id === pane.id || p.value === pane.value
6689
+ );
6690
+ if (existingIndex === -1) {
6691
+ panes.value.push(pane);
6692
+ } else {
6693
+ panes.value[existingIndex] = pane;
6694
+ }
6695
+ }
6696
+ function removePane(id) {
6697
+ const index2 = panes.value.findIndex((p) => p.id === id);
6698
+ if (index2 !== -1) {
6699
+ panes.value.splice(index2, 1);
6700
+ }
6701
+ }
6702
+ function getPaneByValue(value) {
6703
+ return panes.value.find((p) => p.value === value);
6686
6704
  }
6687
6705
  function changeValue(value) {
6688
6706
  emits("update:modelValue", value);
@@ -6697,6 +6715,8 @@ const _sfc_main$u = /* @__PURE__ */ defineComponent({
6697
6715
  });
6698
6716
  provide(tabsKey$1, {
6699
6717
  addPane,
6718
+ removePane,
6719
+ getPaneByValue,
6700
6720
  changeValue
6701
6721
  });
6702
6722
  const getBarStyle = () => {
@@ -6709,9 +6729,12 @@ const _sfc_main$u = /* @__PURE__ */ defineComponent({
6709
6729
  if (!$el)
6710
6730
  return false;
6711
6731
  if ($el.clientWidth === 0 && index2 === 0) {
6712
- nextTick(() => {
6713
- update();
6714
- });
6732
+ if (updateRetryCount.value < maxRetryCount) {
6733
+ updateRetryCount.value++;
6734
+ nextTick(() => {
6735
+ update();
6736
+ });
6737
+ }
6715
6738
  return false;
6716
6739
  }
6717
6740
  if (tab.value !== props.modelValue) {
@@ -6721,6 +6744,7 @@ const _sfc_main$u = /* @__PURE__ */ defineComponent({
6721
6744
  tab.setActive(true);
6722
6745
  offset2 = $el["offsetLeft"];
6723
6746
  tabSize = $el["clientWidth"];
6747
+ updateRetryCount.value = 0;
6724
6748
  return false;
6725
6749
  });
6726
6750
  } else {
@@ -6851,8 +6875,9 @@ const _sfc_main$u = /* @__PURE__ */ defineComponent({
6851
6875
  barStyle.value = getBarStyle();
6852
6876
  getNavOffset();
6853
6877
  };
6878
+ const debouncedUpdate = useDebounceFn(update, 100);
6854
6879
  if (isBrowser) {
6855
- useResizeObserver(tabsRef, update);
6880
+ useResizeObserver(tabsRef, debouncedUpdate);
6856
6881
  }
6857
6882
  onMounted(() => {
6858
6883
  update();
@@ -6916,19 +6941,35 @@ const _sfc_main$t = /* @__PURE__ */ defineComponent({
6916
6941
  const props = __props;
6917
6942
  const tabPaneRef = ref();
6918
6943
  const tabContext = inject(tabsKey, void 0);
6944
+ const isActive = ref(false);
6945
+ const paneId = Math.random().toString(36).substring(2, 10);
6919
6946
  function changeValue() {
6920
- tabContext.changeValue(props.value);
6947
+ if (tabContext) {
6948
+ tabContext.changeValue(props.value);
6949
+ }
6921
6950
  }
6922
- const isActive = ref(false);
6923
6951
  function setActive(active) {
6924
6952
  isActive.value = active;
6925
6953
  }
6926
6954
  onMounted(() => {
6927
- tabContext.addPane(reactive({
6928
- ref: tabPaneRef.value,
6929
- value: props.value,
6930
- setActive
6931
- }));
6955
+ var _a;
6956
+ if (tabContext) {
6957
+ const existingPane = (_a = tabContext.getPaneByValue) == null ? void 0 : _a.call(tabContext, props.value);
6958
+ if (!existingPane) {
6959
+ tabContext.addPane(reactive({
6960
+ id: paneId,
6961
+ ref: tabPaneRef.value,
6962
+ value: props.value,
6963
+ setActive
6964
+ }));
6965
+ }
6966
+ }
6967
+ });
6968
+ onUnmounted(() => {
6969
+ var _a;
6970
+ if (tabContext) {
6971
+ (_a = tabContext.removePane) == null ? void 0 : _a.call(tabContext, paneId);
6972
+ }
6932
6973
  });
6933
6974
  return (_ctx, _cache) => {
6934
6975
  return openBlock(), createElementBlock("div", {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bge-ui",
3
- "version": "1.9.0",
3
+ "version": "1.9.2",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "main": "./src/index.ts",
@@ -11,7 +11,7 @@
11
11
  </div>
12
12
  </template>
13
13
  <script setup lang="ts">
14
- import { useResizeObserver } from "@vueuse/core"
14
+ import { useResizeObserver, useDebounceFn } from "@vueuse/core"
15
15
  import { provide, ref, onMounted, watch, computed, nextTick } from "vue"
16
16
 
17
17
  // 检测是否在浏览器环境中
@@ -41,6 +41,7 @@ const emits = defineEmits(['update:modelValue'])
41
41
 
42
42
  // 类型定义
43
43
  interface TabPane {
44
+ id: string
44
45
  ref: HTMLElement | null
45
46
  value: string
46
47
  setActive: (active: boolean) => void
@@ -51,6 +52,8 @@ const panes = ref<TabPane[]>([])
51
52
  const barStyle = ref<{ width: string; transform: string } | undefined>()
52
53
  const navOffset = ref(0)
53
54
  const scrollable = ref(false)
55
+ const updateRetryCount = ref(0)
56
+ const maxRetryCount = 3
54
57
 
55
58
  // 引用
56
59
  const tabsRef = ref<HTMLElement | null>(null)
@@ -58,7 +61,27 @@ const navScrollRef = ref<HTMLElement | null>(null)
58
61
 
59
62
  // 方法
60
63
  function addPane(pane: TabPane) {
61
- panes.value.push(pane)
64
+ // 检查是否已存在相同 id 或 valuepane,避免重复添加
65
+ const existingIndex = panes.value.findIndex(
66
+ (p) => p.id === pane.id || p.value === pane.value
67
+ )
68
+ if (existingIndex === -1) {
69
+ panes.value.push(pane)
70
+ } else {
71
+ // 更新已存在的 pane
72
+ panes.value[existingIndex] = pane
73
+ }
74
+ }
75
+
76
+ function removePane(id: string) {
77
+ const index = panes.value.findIndex((p) => p.id === id)
78
+ if (index !== -1) {
79
+ panes.value.splice(index, 1)
80
+ }
81
+ }
82
+
83
+ function getPaneByValue(value: string) {
84
+ return panes.value.find((p) => p.value === value)
62
85
  }
63
86
 
64
87
  function changeValue(value: string) {
@@ -77,6 +100,8 @@ watch(() => props.modelValue, () => {
77
100
  const tabsKey = 'bge-tabs-context'
78
101
  provide(tabsKey, {
79
102
  addPane,
103
+ removePane,
104
+ getPaneByValue,
80
105
  changeValue
81
106
  })
82
107
 
@@ -91,9 +116,12 @@ const getBarStyle = (): { width: string; transform: string } => {
91
116
  const $el = tab.ref
92
117
  if (!$el) return false
93
118
  if ($el.clientWidth === 0 && index === 0) {
94
- nextTick(() => {
95
- update()
96
- })
119
+ if (updateRetryCount.value < maxRetryCount) {
120
+ updateRetryCount.value++
121
+ nextTick(() => {
122
+ update()
123
+ })
124
+ }
97
125
  return false
98
126
  }
99
127
  if (tab.value !== props.modelValue) {
@@ -104,6 +132,7 @@ const getBarStyle = (): { width: string; transform: string } => {
104
132
  tab.setActive(true)
105
133
  offset = $el['offsetLeft']
106
134
  tabSize = $el['clientWidth']
135
+ updateRetryCount.value = 0
107
136
  return false
108
137
  })
109
138
  } else {
@@ -237,9 +266,11 @@ const update = () => {
237
266
  getNavOffset()
238
267
  }
239
268
 
269
+ const debouncedUpdate = useDebounceFn(update, 100)
270
+
240
271
  // 仅在浏览器环境中使用 ResizeObserver
241
272
  if (isBrowser) {
242
- useResizeObserver(tabsRef, update)
273
+ useResizeObserver(tabsRef, debouncedUpdate)
243
274
  }
244
275
 
245
276
  onMounted(() => {
@@ -14,23 +14,44 @@ const props = defineProps({
14
14
  type: String
15
15
  }
16
16
  })
17
- import { ref, onMounted, inject, reactive } from "vue";
17
+ import { ref, onMounted, inject, reactive, onUnmounted } from "vue";
18
18
  const tabPaneRef = ref<HTMLDivElement>()
19
19
  const tabsKey = 'bge-tabs-context'
20
20
  const tabContext: any = inject(tabsKey, undefined)
21
+ const isActive = ref<Boolean>(false)
22
+
23
+ // 生成唯一标识,用于去重
24
+ const paneId = Math.random().toString(36).substring(2, 10)
25
+
21
26
  function changeValue() {
22
- tabContext.changeValue(props.value)
27
+ if (tabContext) {
28
+ tabContext.changeValue(props.value)
29
+ }
23
30
  }
24
- const isActive = ref<Boolean>(false)
31
+
25
32
  function setActive(active: Boolean) {
26
33
  isActive.value = active
27
34
  }
35
+
28
36
  onMounted(() => {
29
- tabContext.addPane(reactive({
30
- ref: tabPaneRef.value,
31
- value: props.value,
32
- setActive
33
- }))
37
+ if (tabContext) {
38
+ // 检查是否已存在相同 value 的 pane,避免重复添加
39
+ const existingPane = tabContext.getPaneByValue?.(props.value)
40
+ if (!existingPane) {
41
+ tabContext.addPane(reactive({
42
+ id: paneId,
43
+ ref: tabPaneRef.value,
44
+ value: props.value,
45
+ setActive
46
+ }))
47
+ }
48
+ }
49
+ })
50
+
51
+ onUnmounted(() => {
52
+ if (tabContext) {
53
+ tabContext.removePane?.(paneId)
54
+ }
34
55
  })
35
56
  </script>
36
57
  <style lang="scss" >