vite-uni-dev-tool 0.0.1

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 (69) hide show
  1. package/README.md +120 -0
  2. package/dev/components/Button/index.vue +34 -0
  3. package/dev/components/Checkbox/index.vue +40 -0
  4. package/dev/components/CloseButton/index.vue +25 -0
  5. package/dev/components/Connection/index.vue +98 -0
  6. package/dev/components/ConsoleList/ConsoleItem.vue +89 -0
  7. package/dev/components/ConsoleList/index.vue +98 -0
  8. package/dev/components/DevTool/index.vue +165 -0
  9. package/dev/components/DevToolButton/index.vue +213 -0
  10. package/dev/components/DevToolWindow/index.vue +847 -0
  11. package/dev/components/DeviceInfo/index.vue +32 -0
  12. package/dev/components/Empty/empty.png +0 -0
  13. package/dev/components/Empty/index.vue +28 -0
  14. package/dev/components/FilterInput/index.vue +86 -0
  15. package/dev/components/JsonPretty/components/Brackets/index.vue +23 -0
  16. package/dev/components/JsonPretty/components/Carets/index.vue +63 -0
  17. package/dev/components/JsonPretty/components/CheckController/index.vue +108 -0
  18. package/dev/components/JsonPretty/components/TreeNode/index.vue +348 -0
  19. package/dev/components/JsonPretty/hooks/useClipboard.ts +21 -0
  20. package/dev/components/JsonPretty/hooks/useError.ts +21 -0
  21. package/dev/components/JsonPretty/index.vue +463 -0
  22. package/dev/components/JsonPretty/type.ts +123 -0
  23. package/dev/components/JsonPretty/utils/index.ts +172 -0
  24. package/dev/components/NetworkList/NetworkDetail.vue +197 -0
  25. package/dev/components/NetworkList/NetworkItem.vue +106 -0
  26. package/dev/components/NetworkList/index.vue +108 -0
  27. package/dev/components/PiniaList/index.vue +64 -0
  28. package/dev/components/RouteList/index.vue +98 -0
  29. package/dev/components/SettingList/index.vue +235 -0
  30. package/dev/components/StorageList/index.vue +170 -0
  31. package/dev/components/SystemInfo/index.vue +34 -0
  32. package/dev/components/Tabs/index.vue +110 -0
  33. package/dev/components/Tag/index.vue +89 -0
  34. package/dev/components/UploadList/UploadDetail.vue +208 -0
  35. package/dev/components/UploadList/UploadItem.vue +111 -0
  36. package/dev/components/UploadList/index.vue +94 -0
  37. package/dev/components/VuexList/index.vue +54 -0
  38. package/dev/components/WebSocket/WebSocketItem.vue +98 -0
  39. package/dev/components/WebSocket/WebSocketList.vue +176 -0
  40. package/dev/components/WebSocket/index.vue +99 -0
  41. package/dev/components/WindowInfo/index.vue +33 -0
  42. package/dev/const.ts +95 -0
  43. package/dev/core.ts +103 -0
  44. package/dev/devConsole/index.ts +334 -0
  45. package/dev/devEvent/index.ts +665 -0
  46. package/dev/devIntercept/index.ts +629 -0
  47. package/dev/devStore/index.ts +581 -0
  48. package/dev/index.d.ts +6 -0
  49. package/dev/index.d.ts.map +1 -0
  50. package/dev/index.js +1 -0
  51. package/dev/plugins/uniDevTool/uniDevTool.d.ts +66 -0
  52. package/dev/plugins/uniDevTool/uniDevTool.d.ts.map +1 -0
  53. package/dev/plugins/uniDevTool/uniDevTool.js +13 -0
  54. package/dev/plugins/uniGlobalComponents/uniGlobalComponents.d.ts +28 -0
  55. package/dev/plugins/uniGlobalComponents/uniGlobalComponents.d.ts.map +1 -0
  56. package/dev/plugins/uniGlobalComponents/uniGlobalComponents.js +5 -0
  57. package/dev/shims-uni.d.ts +43 -0
  58. package/dev/type.ts +188 -0
  59. package/dev/utils/date.ts +75 -0
  60. package/dev/utils/file.ts +121 -0
  61. package/dev/utils/function.ts +192 -0
  62. package/dev/utils/index.ts +25 -0
  63. package/dev/utils/ip.ts +79 -0
  64. package/dev/utils/language.ts +19 -0
  65. package/dev/utils/object.ts +235 -0
  66. package/dev/utils/page.ts +13 -0
  67. package/dev/utils/string.ts +23 -0
  68. package/dev/utils/utils.ts +198 -0
  69. package/package.json +34 -0
@@ -0,0 +1,98 @@
1
+ <template>
2
+ <view class="route-content">
3
+ <view class="route-control">
4
+ <FilterInput
5
+ style="width: 100%"
6
+ placeholder="搜索name/path"
7
+ :modelValue="modelValue"
8
+ @search="emit('search', $event)"
9
+ @update:modelValue="emit('update:modelValue', $event)"
10
+ />
11
+ <Tag mode="clear" @click="onRefresh">刷新</Tag>
12
+ </view>
13
+ <view class="route-list">
14
+ <view class="route-item" v-for="item in routeList" :key="item.path">
15
+ <view class="route-item-name">
16
+ <view v-html="item.name" />
17
+ <Tag v-if="item.isNav" mode="info">Nav</Tag>
18
+ <Tag mode="warn" v-if="item.index === 4 || item.index === 3">
19
+ 当前页
20
+ </Tag>
21
+ <Tag mode="primary" v-if="item.index === 4 || item.index === 2">
22
+ 启动页
23
+ </Tag>
24
+ </view>
25
+ <view class="route-item-path">
26
+ <view v-html="item.path" />
27
+ <Tag mode="main" @click="onGoTo(item)">跳转</Tag>
28
+ </view>
29
+ </view>
30
+ <Empty v-if="!routeList || routeList.length === 0" text="暂无路由信息" />
31
+ </view>
32
+ </view>
33
+ </template>
34
+ <script lang="ts" setup>
35
+ import Tag from '../Tag/index.vue';
36
+ import Empty from '../Empty/index.vue';
37
+ import FilterInput from '../FilterInput/index.vue';
38
+ import type { DevTool } from '../../type';
39
+ defineProps<{ routeList: DevTool.Page[]; modelValue?: string }>();
40
+ const emit = defineEmits<{
41
+ (e: 'goTo', params: DevTool.Page): void;
42
+ (e: 'search', value: string): void;
43
+ (e: 'update:modelValue', value: string): void;
44
+ (e: 'routeRefresh'): void;
45
+ }>();
46
+
47
+ function onGoTo(page: DevTool.Page) {
48
+ emit('goTo', page);
49
+ }
50
+ function onRefresh() {
51
+ emit('routeRefresh');
52
+ }
53
+ </script>
54
+ <style scoped>
55
+ .route-content {
56
+ height: 100%;
57
+
58
+ font-size: var(--dev-tool-base-font-size);
59
+ }
60
+
61
+ .route-control {
62
+ display: flex;
63
+ align-items: center;
64
+ justify-content: flex-end;
65
+ gap: 8px;
66
+ padding: 0 16px;
67
+ height: 32px;
68
+ border-bottom: 1px solid var(--dev-tool-border-color);
69
+ box-sizing: border-box;
70
+ }
71
+
72
+ .route-list {
73
+ height: calc(100% - 32px);
74
+ overflow: auto;
75
+ }
76
+ .route-content .route-item {
77
+ padding: 16px;
78
+ border-bottom: 1px solid var(--dev-tool-border-color);
79
+ }
80
+ .route-content .route-item .route-item-name {
81
+ display: flex;
82
+ align-items: center;
83
+ margin-bottom: 8px;
84
+ gap: 12px;
85
+ }
86
+
87
+ .route-content .route-item .route-item-path {
88
+ display: flex;
89
+ align-items: center;
90
+ justify-content: space-between;
91
+ word-break: break-all;
92
+ }
93
+ /* #ifdef APP-PLUS */
94
+ .route-content .route-item .route-item-path :deep(.tag) {
95
+ margin-left: 16px;
96
+ }
97
+ /* #endif */
98
+ </style>
@@ -0,0 +1,235 @@
1
+ <template>
2
+ <view class="setting-content">
3
+ <view class="setting-item">
4
+ <view class="setting-item-title">DevTool</view>
5
+ <view class="setting-item-content">
6
+ <view class="setting-row">
7
+ <view>显示调试按钮:</view>
8
+ <Checkbox
9
+ v-model="setting.showDevButton"
10
+ @change="onChangeShowDevButton"
11
+ />
12
+ </view>
13
+ <view class="setting-tips"> 取消后将不在展示调试按钮 </view>
14
+ <view class="setting-row">
15
+ <view>重启调试器:</view>
16
+ </view>
17
+
18
+ <view class="setting-tips">点击后将会重启调试器</view>
19
+ <DButton class="setting-button" @click="onRestartDevTool(true)">
20
+ 重启调试器
21
+ </DButton>
22
+
23
+ <view class="setting-row">
24
+ <view>销毁调试器:</view>
25
+ </view>
26
+
27
+ <view class="setting-tips">
28
+ 点击后将会销毁调试器,销毁后不再接收调试信息,需要通过
29
+ createDevTool() 重新创建
30
+ </view>
31
+ <DButton class="setting-button" @click="onDestructionDevTool">
32
+ 销毁调试器
33
+ </DButton>
34
+
35
+ <view class="setting-row">
36
+ <view>重启APP:</view>
37
+ </view>
38
+ <view class="setting-tips">点击后将会重启APP</view>
39
+ <DButton class="setting-button" @click="onRestartApp(true)">
40
+ 重启APP
41
+ </DButton>
42
+ <view class="setting-row">
43
+ <view>占用存储空间:{{ sizeFormat }}</view>
44
+ </view>
45
+ <view class="setting-tips">
46
+ 当前所有信息占用的存储空间,只会清除 Console, Network, Upload,
47
+ Websocket
48
+ </view>
49
+ <DButton class="setting-button" @click="onClearCache">
50
+ 清除缓存
51
+ </DButton>
52
+ </view>
53
+ </view>
54
+ <view class="setting-item">
55
+ <view class="setting-item-title">Log</view>
56
+ <view class="setting-item-content">
57
+ <view class="setting-row">
58
+ <view>导出当前日志信息:</view>
59
+ <Checkbox v-model="setting.exportLog" />
60
+ </view>
61
+ <view class="setting-tips">勾选后将会导出当前的Log</view>
62
+ <view class="setting-row">
63
+ <view>导出当前网络信息:</view>
64
+ <Checkbox v-model="setting.exportNetwork" />
65
+ </view>
66
+ <view class="setting-tips">勾选后将会导出当前的Network</view>
67
+ <view class="setting-row">
68
+ <view>导出当前上传信息:</view>
69
+ <Checkbox v-model="setting.exportUpload" />
70
+ </view>
71
+ <view class="setting-tips">勾选后将会导出当前的Upload</view>
72
+ <view class="setting-row">
73
+ <view>导出当前套接字信息:</view>
74
+ <Checkbox v-model="setting.exportWebsocket" />
75
+ </view>
76
+ <view class="setting-tips">勾选后将会导出当前的Websocket</view>
77
+ <view class="setting-row">
78
+ <view>导出当前缓存信息:</view>
79
+ <Checkbox v-model="setting.exportStorage" />
80
+ </view>
81
+ <view class="setting-tips">
82
+ 勾选后将会导出当前的Storage, Vuex, Pinia
83
+ </view>
84
+ <view class="setting-row">
85
+ <view>导出当前窗口信息:</view>
86
+ <Checkbox v-model="setting.exportWindow" />
87
+ </view>
88
+ <view class="setting-tips">勾选后将会导出当前的Window</view>
89
+
90
+ <view class="setting-row">
91
+ <view>导出当前设备信息:</view>
92
+ <Checkbox v-model="setting.exportDevice" />
93
+ </view>
94
+ <view class="setting-tips">勾选后将会导出当前的Device</view>
95
+
96
+ <view class="setting-row">
97
+ <view>导出当前系统信息:</view>
98
+ <Checkbox v-model="setting.exportSystem" />
99
+ </view>
100
+ <view class="setting-tips">勾选后将会导出当前的System</view>
101
+
102
+ <DButton class="setting-button" @click="onExportLog"> 导出 </DButton>
103
+ </view>
104
+ </view>
105
+
106
+ <!--
107
+ <view class="setting-item">
108
+ <view class="setting-item-title">截图</view>
109
+ <DButton
110
+ class="setting-button"
111
+
112
+ @click="onScreenshot"
113
+ >
114
+ 截图当前路由
115
+ </DButton>
116
+ </view>
117
+ -->
118
+ </view>
119
+ </template>
120
+ <script lang="ts" setup>
121
+ import { reactive } from 'vue';
122
+ import Checkbox from '../Checkbox/index.vue';
123
+ import DButton from '../Button/index.vue';
124
+ const props = defineProps<{
125
+ devToolVisible?: boolean;
126
+ sizeFormat?: string;
127
+ }>();
128
+ const setting = reactive({
129
+ showDevButton: props.devToolVisible,
130
+
131
+ restartDevTool: false,
132
+ restartApp: false,
133
+ exportLog: false,
134
+ exportNetwork: false,
135
+ exportUpload: false,
136
+ exportStorage: false,
137
+ exportWebsocket: false,
138
+ exportWindow: false,
139
+ exportDevice: false,
140
+ exportSystem: false,
141
+ });
142
+ const emit = defineEmits<{
143
+ (e: 'showDevButton', show: boolean): void;
144
+ (e: 'restartDevTool', restart?: boolean): void;
145
+ (e: 'restartApp', restart?: boolean): void;
146
+ (
147
+ e: 'exportLog',
148
+ params: {
149
+ exportLog: boolean;
150
+ exportNetwork: boolean;
151
+ exportStorage: boolean;
152
+ exportWebsocket: boolean;
153
+ exportUpload: boolean;
154
+ exportWindow: boolean;
155
+ exportDevice: boolean;
156
+ exportSystem: boolean;
157
+ },
158
+ ): void;
159
+ (e: 'screenshot'): void;
160
+ (e: 'clearCache'): void;
161
+ (e: 'destroyDevTool'): void;
162
+ }>();
163
+
164
+ function onChangeShowDevButton(show: boolean) {
165
+ emit('showDevButton', show);
166
+ }
167
+ function onRestartDevTool(restart: boolean) {
168
+ console.log('restart: ', restart);
169
+ restart && emit('restartDevTool');
170
+ }
171
+
172
+ function onDestructionDevTool() {
173
+ emit('destroyDevTool');
174
+ }
175
+
176
+ function onRestartApp(restart: boolean) {
177
+ restart && emit('restartApp');
178
+ }
179
+ function onExportLog() {
180
+ if (setting.exportLog || setting.exportNetwork || setting.exportStorage) {
181
+ emit('exportLog', {
182
+ exportLog: setting.exportLog,
183
+ exportNetwork: setting.exportNetwork,
184
+ exportStorage: setting.exportStorage,
185
+ exportWebsocket: setting.exportWebsocket,
186
+ exportUpload: setting.exportUpload,
187
+ exportWindow: setting.exportWindow,
188
+ exportDevice: setting.exportDevice,
189
+ exportSystem: setting.exportSystem,
190
+ });
191
+ }
192
+ }
193
+ function onScreenshot() {
194
+ emit('screenshot');
195
+ }
196
+
197
+ function onClearCache() {
198
+ emit('clearCache');
199
+ }
200
+ </script>
201
+ <style scoped>
202
+ .setting-content {
203
+ height: 100%;
204
+ overflow: auto;
205
+ font-size: var(--dev-tool-base-font-size);
206
+ }
207
+ .setting-content .setting-item {
208
+ padding: 16px 16px 0 16px;
209
+ box-sizing: border-box;
210
+ }
211
+ .setting-content .setting-item .setting-item-title {
212
+ display: flex;
213
+ align-items: center;
214
+ }
215
+ .setting-content .setting-item .setting-item-title::before {
216
+ content: '';
217
+ margin-right: 8px;
218
+ width: 2px;
219
+ height: 18px;
220
+ border-radius: 2px;
221
+ background-color: var(--dev-tool-main-color);
222
+ }
223
+ .setting-content .setting-item .setting-item-content .setting-row {
224
+ display: flex;
225
+ align-items: center;
226
+ justify-content: space-between;
227
+ margin: 8px 0;
228
+ min-height: 18px;
229
+ }
230
+ .setting-content .setting-tips {
231
+ color: #616161;
232
+ font-size: var(--dev-tool-tips-font-size);
233
+ margin-bottom: 8px;
234
+ }
235
+ </style>
@@ -0,0 +1,170 @@
1
+ <template>
2
+ <view class="storage-content">
3
+ <view class="storage-control">
4
+ <FilterInput
5
+ :modelValue="modelValue"
6
+ style="width: 100%"
7
+ placeholder="查询key"
8
+ @search="emit('search', $event)"
9
+ @update:modelValue="emit('update:modelValue', $event)"
10
+ />
11
+ <Tag
12
+ v-for="item in storageFilerItem"
13
+ mode="clear"
14
+ :key="item.label"
15
+ @click="onChoose(item.value)"
16
+ >
17
+ {{ item.label }}
18
+ </Tag>
19
+ </view>
20
+ <view class="storage-list">
21
+ <view class="storage-item" v-for="item in storageList" :key="item.key">
22
+ <view class="storage-key">
23
+ <view class="storage-key-label">
24
+ <view>key: </view>
25
+ <view v-html="item._oldKey" />
26
+ </view>
27
+ <CloseButton style="margin-left: auto" @click="onRemove(item.key)" />
28
+ </view>
29
+
30
+ <JsonPretty
31
+ :data="{
32
+ key: item.key,
33
+ value: item.value,
34
+ }"
35
+ showLength
36
+ editable
37
+ @update:data="onUpdateData($event, item)"
38
+ />
39
+ </view>
40
+ <Empty v-if="!storageList || storageList.length === 0" />
41
+ </view>
42
+ </view>
43
+ </template>
44
+ <script lang="ts" setup>
45
+ import Tag from '../Tag/index.vue';
46
+ import JsonPretty from '../JsonPretty/index.vue';
47
+ import Empty from '../Empty/index.vue';
48
+ import CloseButton from '../CloseButton/index.vue';
49
+ import FilterInput from '../FilterInput/index.vue';
50
+ import type { DevTool } from '../../type';
51
+ const props = defineProps<{
52
+ storageList: DevTool.StorageItem[];
53
+ modelValue: string;
54
+ }>();
55
+
56
+ const emit = defineEmits<{
57
+ (e: 'choose', type: string): void;
58
+ (e: 'remove', key: string): void;
59
+ (e: 'update:storageList', data: Record<string, any>): void;
60
+ (e: 'diffValue', value: any): void;
61
+ (e: 'update:modelValue', value: string): void;
62
+ (e: 'search', value: string): void;
63
+ }>();
64
+
65
+ function onUpdateData(
66
+ data: DevTool.StorageItem,
67
+ item: DevTool.StorageItem,
68
+ ) {
69
+ const tempList = JSON.parse(JSON.stringify(props.storageList));
70
+ const index = props.storageList.findIndex(
71
+ (store) => store.key === item._oldKey,
72
+ );
73
+ if (index === -1) return;
74
+ tempList[index] = {
75
+ key: data.key,
76
+ _oldKey: tempList[index]._oldKey,
77
+ value: data.value,
78
+ };
79
+
80
+ emit('update:storageList', tempList);
81
+ emit('diffValue', {
82
+ ...data,
83
+ _oldKey: tempList[index]._oldKey,
84
+ key: data.key,
85
+ });
86
+ }
87
+
88
+ const storageFilerItem = [
89
+ {
90
+ label: '新增',
91
+ value: 'add',
92
+ },
93
+ {
94
+ label: '刷新',
95
+ value: 'refresh',
96
+ },
97
+ {
98
+ label: '清除',
99
+ value: 'clear',
100
+ },
101
+ ];
102
+ function calcValue(value: string) {
103
+ try {
104
+ return {
105
+ value: JSON.parse(value),
106
+ type: 'object',
107
+ };
108
+ } catch (error) {
109
+ return {
110
+ value,
111
+ type: 'string',
112
+ };
113
+ }
114
+ }
115
+ function onChoose(type: string) {
116
+ emit('choose', type);
117
+ }
118
+ function onRemove(key: string) {
119
+ emit('remove', key);
120
+ }
121
+ </script>
122
+ <style scoped>
123
+ .storage-content {
124
+ height: 100%;
125
+ font-size: var(--dev-tool-base-font-size);
126
+ }
127
+ .storage-content .storage-list {
128
+ height: calc(100% - 32px);
129
+ overflow: auto;
130
+ }
131
+ .storage-content .storage-list .storage-item {
132
+ padding: 16px;
133
+ border-bottom: 1px solid var(--dev-tool-border-color);
134
+ }
135
+ .storage-content .storage-list .storage-item .storage-key {
136
+ display: flex;
137
+ align-items: center;
138
+ justify-content: space-between;
139
+ word-break: break-all;
140
+ }
141
+ .storage-key-label {
142
+ display: flex;
143
+ align-items: center;
144
+ }
145
+ .storage-content .storage-list .storage-item .storage-value {
146
+ word-break: break-all;
147
+ }
148
+ .storage-content .storage-list .storage-item .storage-remove {
149
+ flex-shrink: 0;
150
+ display: flex;
151
+ align-items: center;
152
+ justify-content: center;
153
+ width: 24px;
154
+ height: 24px;
155
+ margin: auto 0 auto 16px;
156
+ border-radius: 50%;
157
+ border: 1px solid #000;
158
+ box-sizing: border-box;
159
+ }
160
+ .storage-control {
161
+ display: flex;
162
+ align-items: center;
163
+ justify-content: flex-end;
164
+ gap: 8px;
165
+ padding: 0 16px;
166
+ height: 32px;
167
+ border-bottom: 1px solid var(--dev-tool-border-color);
168
+ box-sizing: border-box;
169
+ }
170
+ </style>
@@ -0,0 +1,34 @@
1
+ <template>
2
+ <view class="system-content">
3
+ <JsonPretty :data="systemInfo" showLength v-if="showJson" />
4
+ <Empty v-else />
5
+ </view>
6
+ </template>
7
+ <script lang="ts" setup>
8
+ import { computed } from 'vue';
9
+ import JsonPretty from '../JsonPretty/index.vue';
10
+ import Empty from '../Empty/index.vue';
11
+ const props = defineProps<{
12
+ systemInfo: Record<string, any>;
13
+ }>();
14
+ const showJson = computed(() => {
15
+ try {
16
+ const str = JSON.stringify(props.systemInfo);
17
+ if (typeof props.systemInfo === 'object' && (str === '' || str === '{}')) {
18
+ return false;
19
+ }
20
+ return true;
21
+ } catch (error) {
22
+ return false;
23
+ }
24
+ });
25
+ </script>
26
+ <style scoped>
27
+ .system-content {
28
+ padding: 16px;
29
+ font-size: var(--dev-tool-base-font-size);
30
+
31
+ height: calc(100% - 32px);
32
+ overflow: auto;
33
+ }
34
+ </style>
@@ -0,0 +1,110 @@
1
+ <template>
2
+ <view class="tabs">
3
+ <scroll-view
4
+ class="tabs-list"
5
+ ref="tabsRef"
6
+ scroll-x="true"
7
+ enable-flex="true"
8
+ :scrollLeft="scrollLeft"
9
+ @scroll="onScroll"
10
+ >
11
+ <view
12
+ v-for="item in items"
13
+ :key="item.key"
14
+ :class="`tabs-item ${
15
+ item.key === modelValue ? 'tabs-item-active' : ''
16
+ } `"
17
+ @click="onChangeTabs(item)"
18
+ >
19
+ {{ item.label }}
20
+ </view>
21
+ </scroll-view>
22
+ <view class="tabs-extra">
23
+ <slot name="extra"></slot>
24
+ <CloseButton style="margin: 0 16px" @click="onClose" />
25
+ </view>
26
+ </view>
27
+ </template>
28
+
29
+ <script setup lang="ts">
30
+ import { ref } from 'vue';
31
+ import CloseButton from '../CloseButton/index.vue';
32
+ // const activeKey = ref("Console");
33
+ defineProps<{
34
+ modelValue: string;
35
+ items: { label: string; key: string; value: any }[];
36
+ scrollLeft?: number;
37
+ }>();
38
+
39
+ const tabsRef = ref();
40
+
41
+ const emit = defineEmits<{
42
+ (e: 'close'): void;
43
+ (e: 'update:modelValue', value: string): void;
44
+ (e: 'change', value: string): void;
45
+ (e: 'scroll', value: any): void;
46
+ }>();
47
+ function onChangeTabs(item: { label: string; key: string; value: any }) {
48
+ // activeKey.value = item.key;
49
+ emit('update:modelValue', item.key);
50
+ emit('change', item.key);
51
+ }
52
+ function onClose() {
53
+ emit('close');
54
+ }
55
+
56
+ function onScroll(e: any) {
57
+ emit('scroll', e);
58
+ }
59
+ </script>
60
+
61
+ <style scoped>
62
+ .tabs {
63
+ display: flex;
64
+ align-items: center;
65
+ height: 32px;
66
+ border-bottom: 1px solid var(--dev-tool-border-color);
67
+ box-sizing: border-box;
68
+ font-size: var(--dev-tool-base-font-size);
69
+ }
70
+ .tabs .tabs-list {
71
+ display: flex;
72
+ align-items: center;
73
+ flex: 1;
74
+ overflow: auto;
75
+ -ms-overflow-style: none;
76
+ scrollbar-width: none;
77
+ white-space: nowrap;
78
+ width: 100%;
79
+ }
80
+ .tabs-list ::-webkit-scrollbar {
81
+ display: none;
82
+ width: 0;
83
+ height: 0;
84
+ background-color: transparent;
85
+ }
86
+ .tabs-list ::-webkit-scrollbar-thumb {
87
+ width: 0;
88
+ height: 0;
89
+ background-color: transparent;
90
+ }
91
+ .tabs .tabs-item {
92
+ display: inline-block;
93
+ padding: 0 16px;
94
+ height: 32px;
95
+ line-height: 32px;
96
+ border-bottom: 1px solid transparent;
97
+ box-sizing: border-box;
98
+ transition: all 0.3s;
99
+ cursor: pointer;
100
+ }
101
+ .tabs .tabs-item-active {
102
+ color: var(--dev-tool-main-color);
103
+ border-color: var(--dev-tool-main-color);
104
+ }
105
+
106
+ .tabs-extra {
107
+ display: flex;
108
+ align-items: center;
109
+ }
110
+ </style>