vdesign-ui 0.2.9 → 0.2.12

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 (165) hide show
  1. package/README.md +78 -78
  2. package/dist/components/actionbar/index.js +8 -8
  3. package/dist/components/actionbar/index.vue +39 -39
  4. package/dist/components/actionbar/style.less +44 -44
  5. package/dist/components/actionbar-cell/index.js +7 -7
  6. package/dist/components/actionbar-cell/index.vue +38 -38
  7. package/dist/components/actions/index.js +6 -6
  8. package/dist/components/actions/index.vue +76 -76
  9. package/dist/components/actions/style.less +109 -109
  10. package/dist/components/actions-cell/index.js +6 -6
  11. package/dist/components/actions-cell/index.vue +94 -94
  12. package/dist/components/actions-cell/style.less +38 -38
  13. package/dist/components/activityviews/index.js +8 -8
  14. package/dist/components/activityviews/index.vue +192 -192
  15. package/dist/components/activityviews/style.less +151 -151
  16. package/dist/components/badge/index.js +8 -8
  17. package/dist/components/badge/index.vue +49 -49
  18. package/dist/components/badge/style.less +54 -54
  19. package/dist/components/button/index.js +8 -8
  20. package/dist/components/button/index.vue +93 -93
  21. package/dist/components/button/style.less +558 -558
  22. package/dist/components/calendar/index-element.vue +84 -84
  23. package/dist/components/calendar/index.js +7 -7
  24. package/dist/components/calendar/index.vue +52 -52
  25. package/dist/components/calendar/style.less +138 -138
  26. package/dist/components/checkbox/index.js +8 -8
  27. package/dist/components/checkbox/index.vue +161 -161
  28. package/dist/components/checkbox/style.less +288 -288
  29. package/dist/components/checkbox-group/index.js +7 -7
  30. package/dist/components/checkbox-group/index.vue +69 -69
  31. package/dist/components/common/state/index.vue +33 -33
  32. package/dist/components/common/state/style.less +47 -47
  33. package/dist/components/data-list/index.js +10 -10
  34. package/dist/components/data-list/index.vue +19 -19
  35. package/dist/components/data-list/style.less +623 -623
  36. package/dist/components/datetime-picker/index.js +7 -7
  37. package/dist/components/datetime-picker/index.vue +37 -37
  38. package/dist/components/datetime-picker/style.less +23 -23
  39. package/dist/components/dialog/index.js +8 -8
  40. package/dist/components/dialog/index.vue +164 -164
  41. package/dist/components/dialog/overlay-manager.js +18 -18
  42. package/dist/components/dialog/style.less +138 -138
  43. package/dist/components/divider/index.js +8 -8
  44. package/dist/components/divider/index.vue +54 -54
  45. package/dist/components/divider/style.less +92 -92
  46. package/dist/components/dropdown/index.js +8 -8
  47. package/dist/components/dropdown/index.vue +218 -218
  48. package/dist/components/dropdown/style.less +432 -432
  49. package/dist/components/empty/index.js +8 -8
  50. package/dist/components/empty/index.vue +138 -138
  51. package/dist/components/empty/style.less +60 -60
  52. package/dist/components/footer/index.js +6 -6
  53. package/dist/components/footer/index.vue +33 -33
  54. package/dist/components/footer/style.less +20 -20
  55. package/dist/components/footnav/index.js +6 -6
  56. package/dist/components/footnav/index.vue +93 -93
  57. package/dist/components/footnav/style.less +22 -22
  58. package/dist/components/footnav-item/index.js +6 -6
  59. package/dist/components/footnav-item/index.vue +50 -50
  60. package/dist/components/footnav-item/style.less +39 -39
  61. package/dist/components/form/index.js +6 -6
  62. package/dist/components/form/index.vue +12 -12
  63. package/dist/components/headnav/index.js +6 -6
  64. package/dist/components/headnav/index.vue +185 -185
  65. package/dist/components/headnav/style.less +231 -231
  66. package/dist/components/icon/font/iconfont.css +163 -163
  67. package/dist/components/icon/font/iconfont.js +5 -5
  68. package/dist/components/icon/index.js +9 -9
  69. package/dist/components/icon/index.vue +96 -96
  70. package/dist/components/icon/style.less +44 -44
  71. package/dist/components/input/calcTextareaHeight.js +162 -162
  72. package/dist/components/input/index.js +8 -8
  73. package/dist/components/input/index.vue +345 -345
  74. package/dist/components/input/style.less +470 -470
  75. package/dist/components/list/index.js +8 -8
  76. package/dist/components/list/index.vue +152 -152
  77. package/dist/components/list/style.less +213 -213
  78. package/dist/components/loading/index.js +6 -6
  79. package/dist/components/loading/index.vue +68 -68
  80. package/dist/components/loading/style.less +53 -53
  81. package/dist/components/mixins/clickoutside.js +81 -81
  82. package/dist/components/mixins/languageMixin.js +41 -41
  83. package/dist/components/mixins/outlineConfigPlugin.js +45 -45
  84. package/dist/components/mixins/themeMixin.js +43 -43
  85. package/dist/components/noticebar/index.js +8 -8
  86. package/dist/components/noticebar/index.vue +258 -258
  87. package/dist/components/noticebar/style.less +328 -328
  88. package/dist/components/overlay/index.js +8 -8
  89. package/dist/components/overlay/index.vue +184 -184
  90. package/dist/components/overlay/style.less +23 -23
  91. package/dist/components/pagebreak/index.js +6 -6
  92. package/dist/components/pagebreak/index.vue +67 -67
  93. package/dist/components/pagebreak/style.less +41 -41
  94. package/dist/components/password/index.js +8 -8
  95. package/dist/components/password/index.vue +60 -60
  96. package/dist/components/popover/index.js +8 -8
  97. package/dist/components/popover/index.vue +100 -100
  98. package/dist/components/popover/style.less +346 -346
  99. package/dist/components/popover/vue-popover.vue +314 -314
  100. package/dist/components/popup/index.js +7 -7
  101. package/dist/components/popup/index.vue +243 -243
  102. package/dist/components/radio/index.js +8 -8
  103. package/dist/components/radio/index.vue +184 -184
  104. package/dist/components/radio/style.less +293 -293
  105. package/dist/components/radio-group/index.js +6 -6
  106. package/dist/components/radio-group/index.vue +58 -58
  107. package/dist/components/result/index.js +8 -8
  108. package/dist/components/result/index.vue +73 -73
  109. package/dist/components/result/style.less +43 -43
  110. package/dist/components/search/index.js +8 -8
  111. package/dist/components/search/index.vue +66 -66
  112. package/dist/components/selector/index.js +8 -8
  113. package/dist/components/selector/index.vue +161 -161
  114. package/dist/components/selector/style.less +484 -484
  115. package/dist/components/skeleton/index.js +6 -6
  116. package/dist/components/skeleton/index.vue +207 -206
  117. package/dist/components/skeleton/style.less +196 -196
  118. package/dist/components/slider/draggable.js +49 -49
  119. package/dist/components/slider/index.js +6 -6
  120. package/dist/components/slider/index.vue +167 -167
  121. package/dist/components/slider/style.less +99 -99
  122. package/dist/components/slider/utils.js +59 -59
  123. package/dist/components/step/index.js +7 -7
  124. package/dist/components/step/index.vue +48 -48
  125. package/dist/components/step/style.less +57 -57
  126. package/dist/components/step-item/index.js +7 -7
  127. package/dist/components/step-item/index.vue +126 -126
  128. package/dist/components/step-item/style.less +362 -362
  129. package/dist/components/stepper/index.js +8 -8
  130. package/dist/components/stepper/index.vue +146 -146
  131. package/dist/components/style/index.vue +42 -42
  132. package/dist/components/switch/index.js +8 -8
  133. package/dist/components/switch/index.vue +72 -72
  134. package/dist/components/switch/style.less +56 -56
  135. package/dist/components/tab/index.js +7 -7
  136. package/dist/components/tab/index.vue +94 -93
  137. package/dist/components/tabs/index.js +8 -8
  138. package/dist/components/tabs/index.vue +281 -271
  139. package/dist/components/tabs/style.less +408 -409
  140. package/dist/components/tag/index.js +6 -6
  141. package/dist/components/tag/index.vue +64 -64
  142. package/dist/components/tag/style.less +210 -210
  143. package/dist/components/title/index.js +8 -8
  144. package/dist/components/title/index.vue +99 -99
  145. package/dist/components/title/style.less +187 -187
  146. package/dist/components/toast/index.js +97 -86
  147. package/dist/components/toast/index.vue +49 -49
  148. package/dist/components/toast/style.less +57 -57
  149. package/dist/components/transition/index.js +8 -8
  150. package/dist/components/transition/index.vue +13 -13
  151. package/dist/components/transition/style.less +208 -208
  152. package/dist/components/upload/index.js +6 -6
  153. package/dist/components/upload/index.vue +106 -106
  154. package/dist/components/upload/style.less +147 -147
  155. package/dist/components/utils/assist.js +34 -34
  156. package/dist/components/utils/env.js +21 -21
  157. package/dist/locale/ar.js +97 -97
  158. package/dist/locale/en.js +97 -97
  159. package/dist/locale/zh.js +97 -97
  160. package/dist/token.css +2988 -2988
  161. package/dist/vdesign-ui.common.js +308 -8512
  162. package/dist/vdesign-ui.css +1 -1
  163. package/dist/vdesign-ui.umd.js +312 -8516
  164. package/dist/vdesign-ui.umd.min.js +2 -8
  165. package/package.json +113 -113
@@ -1,271 +1,281 @@
1
- <template>
2
- <div class="vd-tabs" :class="stickyClasses">
3
- <div class="vd-tabs__wrap" :class="menuClasses" ref="wrap">
4
- <div class="vd-tabs__nav" :class="[barType, scrollspy]" ref="nav">
5
- <div
6
- v-for="(tab, index) in tabs"
7
- :key="tab.name !== undefined ? tab.name : index"
8
- :class="[tabClasses(tab, index), lineClasses]"
9
- @click="onClick(tab, index)"
10
- ref="tabItems"
11
- >
12
- <span class="vd-tab__text" :class="ellipsisClasses" ref="title"
13
- >
14
- {{ tab.title }}
15
- <!-- <vd-icon
16
- class="vd-tab__arrow"
17
- v-if="tab.arrow"
18
- name="icon_btn_moredown"
19
- ></vd-icon> -->
20
- </span>
21
- </div>
22
- </div>
23
- <div class="vd-tabs__menu--right" v-if="menu">
24
- <vd-icon
25
- :name="menuIconComputed"
26
- class="vd-tabs__menu--btn"
27
- @click="emitMenuClick"
28
- ></vd-icon>
29
- </div>
30
- </div>
31
- <div class="vd-tabs__content" ref="content" :class="{'vd-tabs__content--animated':animated}">
32
- <div v-if="animated" :class="trackClasses" :style="trackStyle">
33
- <slot />
34
- </div>
35
- <slot v-else />
36
- </div>
37
- </div>
38
- </template>
39
-
40
- <script>
41
- import VdIcon from "../icon";
42
- const prefixCls = "vd-tabs";
43
- export default {
44
- name: "vd-tabs",
45
- components: {
46
- VdIcon,
47
- },
48
- props: {
49
- value: [String, Number],
50
- tabsType: {
51
- type: String,
52
- default: "primary",
53
- },
54
- menu: {
55
- type: [Boolean, String],
56
- default: false,
57
- },
58
- ellipsis: {
59
- type: Boolean,
60
- default: true,
61
- },
62
- actBorder: Boolean,
63
- backgroundColor: Boolean,
64
- divider: Boolean,
65
- sticky: Boolean,
66
- lazyRender: Boolean,
67
- animated: Boolean,
68
- },
69
- data() {
70
- return {
71
- tabs: [],
72
- currentName: this.value !== undefined ? this.value : 0, // 默认为 0
73
- };
74
- },
75
- watch: {
76
- // 监听 value 变化,更新 currentValue
77
- value(val) {
78
- this.currentName = val;
79
- this.setCurrentName(val);
80
- },
81
- },
82
- computed: {
83
- trackClasses() {
84
- return {
85
- 'vd-tabs__track': true,
86
- };
87
- },
88
- trackStyle() {
89
- const activeIndex = this.tabs.findIndex((tab, index) => {
90
- return this.isTabActive(tab, index);
91
- });
92
- const translateX = -activeIndex * 100;
93
- return {
94
- transform: `translateX(${translateX}%)`,
95
- transitionDuration: '0.3s',
96
- };
97
- },
98
- // 计算菜单按钮的图标,根据 menu 属性的类型决定图标
99
- menuIconComputed() {
100
- if (typeof this.menu === "string") {
101
- return this.menu;
102
- } else {
103
- return "icon_tab_morelist"; // 默认的菜单图标名称
104
- }
105
- },
106
- // 计算滚动监视的类名
107
- scrollspy() {
108
- return `${prefixCls}--complete`;
109
- },
110
- // 计算标签文字是否需要省略号的类名
111
- ellipsisClasses() {
112
- return {
113
- [`vd-tab__text--ellipsis`]: this.ellipsis,
114
- };
115
- },
116
- // 计算标签包裹器的类名,根据 menu、backgroundColor 和 divider 属性来确定
117
- menuClasses() {
118
- return {
119
- [`${prefixCls}__menu`]: this.menu,
120
- [`${prefixCls}__wrap--bg`]: this.backgroundColor,
121
- "vd-hairline--bottom": this.divider,
122
- };
123
- },
124
- // 计算标签下方线条的类名
125
- lineClasses() {
126
- return {
127
- [`vd-tab__none--line`]: !this.actBorder,
128
- };
129
- },
130
- // 根据 tabsType 属性计算标签类型的类名
131
- barType() {
132
- return {
133
- [`${prefixCls}__nav--${this.tabsType}`]: this.tabsType,
134
- };
135
- },
136
- stickyClasses() {
137
- return {
138
- [`${prefixCls}--sticky`]: this.sticky,
139
- };
140
- },
141
- },
142
- methods: {
143
- // 当菜单按钮被点击时触发事件
144
- emitMenuClick() {
145
- this.$emit("menu-click");
146
- },
147
- // 计算每个标签项的类名
148
- tabClasses(tab, index) {
149
- const isActive = this.isTabActive(tab, index);
150
- return {
151
- 'vd-tab': true,
152
- 'vd-tab--active': isActive,
153
- };
154
- },
155
- setCurrentName(name) {
156
- // 如果没有指定 name 属性,则使用索引值,确保索引值为数字类型
157
- const nameIsNumber = typeof name === 'number' || /^\d+$/.test(name);
158
- const parsedName = nameIsNumber ? Number(name) : name;
159
-
160
- const matchedTab = this.tabs.find((tab, index) => {
161
- if (tab.name !== undefined) {
162
- return tab.name === parsedName;
163
- } else {
164
- return index === parsedName;
165
- }
166
- });
167
-
168
- if (matchedTab) {
169
- this.currentName = matchedTab.name !== undefined ? matchedTab.name : this.tabs.indexOf(matchedTab);
170
- } else if (this.tabs.length > 0) {
171
- const firstTab = this.tabs[0];
172
- this.currentName = firstTab.name !== undefined ? firstTab.name : 0;
173
- } else {
174
- this.currentName = null;
175
- }
176
- this.$emit('input', this.currentName);
177
- },
178
- isTabActive(tab, index) {
179
- if (tab.name !== undefined) {
180
- return tab.name === this.currentName;
181
- } else {
182
- return index === Number(this.currentName);
183
- }
184
- },
185
- addTab(tab) {
186
- this.tabs.push(tab);
187
- if (this.currentName === undefined) {
188
- this.setCurrentName(tab.name !== undefined ? tab.name : 0);
189
- }
190
- },
191
- removeTab(tab) {
192
- const index = this.tabs.indexOf(tab);
193
- if (index !== -1) {
194
- this.tabs.splice(index, 1);
195
- }
196
- },
197
- onClick(tab, index) {
198
- if (tab.disabled) {
199
- this.$emit('disabled', tab.name !== undefined ? tab.name : index, index);
200
- } else {
201
- this.currentName = tab.name !== undefined ? tab.name : index;
202
- // 如果 currentName 是索引值,确保为数字类型
203
- if (tab.name === undefined) {
204
- this.currentName = Number(this.currentName);
205
- }
206
- this.$emit('input', this.currentName);
207
- this.$emit('change', this.currentName, index);
208
- // 切换标签后,滚动到当前标签
209
- this.$nextTick(() => {
210
- this.scrollToActiveTab();
211
- });
212
- }
213
- },
214
- scrollToActiveTab() {
215
- const scrollWrapper = this.$refs.nav; // 修改这里
216
- const tabItems = this.$refs.tabItems;
217
-
218
- if (!scrollWrapper || !tabItems || tabItems.length === 0) {
219
- return;
220
- }
221
-
222
- const activeIndex = this.tabs.findIndex((tab, index) => {
223
- return this.isTabActive(tab, index);
224
- });
225
-
226
- const activeTab = tabItems[activeIndex];
227
-
228
- if (activeTab) {
229
- const tabOffsetLeft = activeTab.offsetLeft;
230
- const tabWidth = activeTab.offsetWidth;
231
- const wrapperWidth = scrollWrapper.offsetWidth;
232
- const scrollLeft = tabOffsetLeft - (wrapperWidth - tabWidth) / 2;
233
-
234
- scrollWrapper.scrollTo({
235
- left: scrollLeft,
236
- behavior: 'smooth',
237
- });
238
- }
239
- },
240
- renderTitle(titleEl, tab) {
241
- this.$nextTick(() => {
242
- const index = this.tabs.indexOf(tab);
243
- if (index !== -1 && this.$refs.title && this.$refs.title[index]) {
244
- const navTitleEl = this.$refs.title[index];
245
- // 清空导航标题元素的内容
246
- navTitleEl.innerHTML = '';
247
- // 将子组件的 title 插槽内容移动到导航标题元素中
248
- while (titleEl.firstChild) {
249
- navTitleEl.appendChild(titleEl.firstChild);
250
- }
251
- }
252
- });
253
- },
254
- },
255
- mounted() {
256
- if (this.currentName !== undefined) {
257
- this.setCurrentName(this.currentName);
258
- } else if (this.tabs.length > 0) {
259
- const firstTab = this.tabs[0];
260
- this.currentName = firstTab.name !== undefined ? firstTab.name : 0;
261
- }
262
- // 初始加载时,滚动到当前激活的标签
263
- this.$nextTick(() => {
264
- this.scrollToActiveTab();
265
- });
266
- },
267
- };
268
- </script>
269
- <style lang="less">
270
- @import "./style.less";
271
- </style>
1
+ <template>
2
+ <div class="vd-tabs" :class="stickyClasses">
3
+ <div class="vd-tabs__wrap" :class="menuClasses" ref="wrap">
4
+ <div class="vd-tabs__nav" :class="[barType, scrollspyClasses]" ref="nav">
5
+ <div
6
+ v-for="(tab, index) in tabs"
7
+ :key="tab.name !== undefined ? tab.name : index"
8
+ :class="[tabClasses(tab, index), lineClasses]"
9
+ @click="onClick(tab, index)"
10
+ ref="tabItems"
11
+ >
12
+ <span class="vd-tab__text" :class="ellipsisClasses" ref="title"
13
+ >
14
+ {{ tab.title }}
15
+ <!-- <vd-icon
16
+ class="vd-tab__arrow"
17
+ v-if="tab.arrow"
18
+ name="icon_btn_moredown"
19
+ ></vd-icon> -->
20
+ </span>
21
+ </div>
22
+ </div>
23
+ <div class="vd-tabs__menu--right" v-if="menu">
24
+ <vd-icon
25
+ :name="menuIconComputed"
26
+ class="vd-tabs__menu--btn"
27
+ @click="emitMenuClick"
28
+ ></vd-icon>
29
+ </div>
30
+ </div>
31
+ <div class="vd-tabs__content" ref="content" :class="{'vd-tabs__content--animated':animated}">
32
+ <div v-if="animated" :class="trackClasses" :style="trackStyle">
33
+ <slot />
34
+ </div>
35
+ <slot v-else />
36
+ </div>
37
+ </div>
38
+ </template>
39
+
40
+ <script>
41
+ import VdIcon from "../icon";
42
+ import languageMixin from '../mixins/languageMixin.js';
43
+
44
+ const prefixCls = "vd-tabs";
45
+ export default {
46
+ name: "vd-tabs",
47
+ mixins: [languageMixin],
48
+ components: {
49
+ VdIcon,
50
+ },
51
+ props: {
52
+ value: [String, Number],
53
+ tabsType: {
54
+ type: String,
55
+ default: "primary",
56
+ },
57
+ menu: {
58
+ type: [Boolean, String],
59
+ default: false,
60
+ },
61
+ ellipsis: {
62
+ type: Boolean,
63
+ default: true,
64
+ },
65
+ actBorder: Boolean,
66
+ backgroundColor: Boolean,
67
+ divider: Boolean,
68
+ sticky: Boolean,
69
+ lazyRender: Boolean,
70
+ animated: Boolean,
71
+ scrollspy:Boolean
72
+ },
73
+ data() {
74
+ return {
75
+ tabs: [],
76
+ currentName: this.value !== undefined ? this.value : 0, // 默认为 0
77
+ };
78
+ },
79
+ watch: {
80
+ // 监听 value 变化,更新 currentValue
81
+ value(val) {
82
+ this.currentName = val;
83
+ this.setCurrentName(val);
84
+ },
85
+ },
86
+ computed: {
87
+ trackClasses() {
88
+ return {
89
+ 'vd-tabs__track': true,
90
+ };
91
+ },
92
+ trackStyle() {
93
+ const activeIndex = this.tabs.findIndex((tab, index) => {
94
+ return this.isTabActive(tab, index);
95
+ });
96
+
97
+ const offset = activeIndex * 100;
98
+ // 根据文本方向调整 translateX
99
+ const translateX = this.language === 'ar' ? offset : -offset;
100
+ // const translateX = -activeIndex * 100;
101
+ return {
102
+ transform: `translateX(${translateX}%)`,
103
+ transitionDuration: '0.3s',
104
+ };
105
+ },
106
+ // 计算菜单按钮的图标,根据 menu 属性的类型决定图标
107
+ menuIconComputed() {
108
+ if (typeof this.menu === "string") {
109
+ return this.menu;
110
+ } else {
111
+ return "icon_tab_morelist"; // 默认的菜单图标名称
112
+ }
113
+ },
114
+ // 计算滚动监视的类名
115
+ scrollspyClasses() {
116
+ return {
117
+ [`${prefixCls}--complete`]:this.scrollspy
118
+ }
119
+ },
120
+ // 计算标签文字是否需要省略号的类名
121
+ ellipsisClasses() {
122
+ return {
123
+ [`vd-tab__text--ellipsis`]: this.ellipsis,
124
+ };
125
+ },
126
+ // 计算标签包裹器的类名,根据 menu、backgroundColor 和 divider 属性来确定
127
+ menuClasses() {
128
+ return {
129
+ [`${prefixCls}__menu`]: this.menu,
130
+ [`${prefixCls}__wrap--bg`]: this.backgroundColor,
131
+ "vd-hairline--bottom": this.divider,
132
+ };
133
+ },
134
+ // 计算标签下方线条的类名
135
+ lineClasses() {
136
+ return {
137
+ [`vd-tab__none--line`]: !this.actBorder,
138
+ };
139
+ },
140
+ // 根据 tabsType 属性计算标签类型的类名
141
+ barType() {
142
+ return {
143
+ [`${prefixCls}__nav--${this.tabsType}`]: this.tabsType,
144
+ };
145
+ },
146
+ stickyClasses() {
147
+ return {
148
+ [`${prefixCls}--sticky`]: this.sticky,
149
+ };
150
+ },
151
+ },
152
+ methods: {
153
+ // 当菜单按钮被点击时触发事件
154
+ emitMenuClick() {
155
+ this.$emit("menu-click");
156
+ },
157
+ // 计算每个标签项的类名
158
+ tabClasses(tab, index) {
159
+ const isActive = this.isTabActive(tab, index);
160
+ return {
161
+ 'vd-tab': true,
162
+ 'vd-tab--active': isActive,
163
+ };
164
+ },
165
+ setCurrentName(name) {
166
+ // 如果没有指定 name 属性,则使用索引值,确保索引值为数字类型
167
+ const nameIsNumber = typeof name === 'number' || /^\d+$/.test(name);
168
+ const parsedName = nameIsNumber ? Number(name) : name;
169
+
170
+ const matchedTab = this.tabs.find((tab, index) => {
171
+ if (tab.name !== undefined) {
172
+ return tab.name === parsedName;
173
+ } else {
174
+ return index === parsedName;
175
+ }
176
+ });
177
+
178
+ if (matchedTab) {
179
+ this.currentName = matchedTab.name !== undefined ? matchedTab.name : this.tabs.indexOf(matchedTab);
180
+ } else if (this.tabs.length > 0) {
181
+ const firstTab = this.tabs[0];
182
+ this.currentName = firstTab.name !== undefined ? firstTab.name : 0;
183
+ } else {
184
+ this.currentName = null;
185
+ }
186
+ this.$emit('input', this.currentName);
187
+ },
188
+ isTabActive(tab, index) {
189
+ if (tab.name !== undefined) {
190
+ return tab.name === this.currentName;
191
+ } else {
192
+ return index === Number(this.currentName);
193
+ }
194
+ },
195
+ addTab(tab) {
196
+ this.tabs.push(tab);
197
+ if (this.currentName === undefined) {
198
+ this.setCurrentName(tab.name !== undefined ? tab.name : 0);
199
+ }
200
+ },
201
+ removeTab(tab) {
202
+ const index = this.tabs.indexOf(tab);
203
+ if (index !== -1) {
204
+ this.tabs.splice(index, 1);
205
+ }
206
+ },
207
+ onClick(tab, index) {
208
+ if (tab.disabled) {
209
+ this.$emit('disabled', tab.name !== undefined ? tab.name : index, index);
210
+ } else {
211
+ this.currentName = tab.name !== undefined ? tab.name : index;
212
+ // 如果 currentName 是索引值,确保为数字类型
213
+ if (tab.name === undefined) {
214
+ this.currentName = Number(this.currentName);
215
+ }
216
+ this.$emit('input', this.currentName);
217
+ this.$emit('change', this.currentName, index);
218
+ // 切换标签后,滚动到当前标签
219
+ this.$nextTick(() => {
220
+ this.scrollToActiveTab();
221
+ });
222
+ }
223
+ },
224
+ scrollToActiveTab() {
225
+ const scrollWrapper = this.$refs.nav; // 修改这里
226
+ const tabItems = this.$refs.tabItems;
227
+
228
+ if (!scrollWrapper || !tabItems || tabItems.length === 0) {
229
+ return;
230
+ }
231
+
232
+ const activeIndex = this.tabs.findIndex((tab, index) => {
233
+ return this.isTabActive(tab, index);
234
+ });
235
+
236
+ const activeTab = tabItems[activeIndex];
237
+
238
+ if (activeTab) {
239
+ const tabOffsetLeft = activeTab.offsetLeft;
240
+ const tabWidth = activeTab.offsetWidth;
241
+ const wrapperWidth = scrollWrapper.offsetWidth;
242
+ const scrollLeft = tabOffsetLeft - (wrapperWidth - tabWidth) / 2;
243
+
244
+ scrollWrapper.scrollTo({
245
+ left: scrollLeft,
246
+ behavior: 'smooth',
247
+ });
248
+ }
249
+ },
250
+ renderTitle(titleEl, tab) {
251
+ this.$nextTick(() => {
252
+ const index = this.tabs.indexOf(tab);
253
+ if (index !== -1 && this.$refs.title && this.$refs.title[index]) {
254
+ const navTitleEl = this.$refs.title[index];
255
+ // 清空导航标题元素的内容
256
+ navTitleEl.innerHTML = '';
257
+ // 将子组件的 title 插槽内容移动到导航标题元素中
258
+ while (titleEl.firstChild) {
259
+ navTitleEl.appendChild(titleEl.firstChild);
260
+ }
261
+ }
262
+ });
263
+ },
264
+ },
265
+ mounted() {
266
+ if (this.currentName !== undefined) {
267
+ this.setCurrentName(this.currentName);
268
+ } else if (this.tabs.length > 0) {
269
+ const firstTab = this.tabs[0];
270
+ this.currentName = firstTab.name !== undefined ? firstTab.name : 0;
271
+ }
272
+ // 初始加载时,滚动到当前激活的标签
273
+ this.$nextTick(() => {
274
+ this.scrollToActiveTab();
275
+ });
276
+ },
277
+ };
278
+ </script>
279
+ <style lang="less">
280
+ @import "./style.less";
281
+ </style>