vite-uni-dev-tool 0.0.13 → 0.0.14

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 (109) hide show
  1. package/dist/v2/AppInfo/index.vue +41 -0
  2. package/dist/v2/AutoSizer/index.vue +189 -0
  3. package/dist/v2/AutoSizer/index1.vue +193 -0
  4. package/dist/v2/AutoSizer/utils.ts +49 -0
  5. package/dist/v2/CaptureScreen/index.vue +78 -0
  6. package/dist/v2/CloseButton/index.vue +32 -0
  7. package/dist/v2/Connection/index.vue +94 -0
  8. package/dist/v2/ConsoleList/ConsoleItem.vue +235 -0
  9. package/dist/v2/ConsoleList/RunJSInput.vue +243 -0
  10. package/dist/v2/ConsoleList/index.vue +164 -0
  11. package/dist/v2/ConsoleList/staticTips.js +1144 -0
  12. package/dist/v2/DevTool/index.vue +162 -0
  13. package/dist/v2/DevToolButton/index.vue +228 -0
  14. package/dist/v2/DevToolTitle/index.vue +28 -0
  15. package/dist/v2/DevToolWindow/index.vue +1051 -0
  16. package/dist/v2/DeviceInfo/index.vue +48 -0
  17. package/dist/v2/Empty/empty.png +0 -0
  18. package/dist/v2/Empty/index.vue +40 -0
  19. package/dist/v2/FilterInput/index.vue +100 -0
  20. package/dist/v2/JsonPretty/components/Brackets/index.vue +30 -0
  21. package/dist/v2/JsonPretty/components/Carets/index.vue +65 -0
  22. package/dist/v2/JsonPretty/components/CheckController/index.vue +127 -0
  23. package/dist/v2/JsonPretty/components/TreeNode/index.vue +417 -0
  24. package/dist/v2/JsonPretty/hooks/useClipboard.ts +21 -0
  25. package/dist/v2/JsonPretty/hooks/useError.ts +21 -0
  26. package/dist/v2/JsonPretty/index.vue +531 -0
  27. package/dist/v2/JsonPretty/type.ts +125 -0
  28. package/dist/v2/JsonPretty/utils/index.js +211 -0
  29. package/dist/v2/NetworkList/NetworkDetail.vue +215 -0
  30. package/dist/v2/NetworkList/NetworkItem.vue +135 -0
  31. package/dist/v2/NetworkList/index.vue +148 -0
  32. package/dist/v2/PiniaList/index.vue +79 -0
  33. package/dist/v2/RouteList/index.vue +137 -0
  34. package/dist/v2/RunJS/index.vue +128 -0
  35. package/dist/v2/SettingList/index.vue +318 -0
  36. package/dist/v2/SourceCode/index.vue +237 -0
  37. package/dist/v2/StorageList/index.vue +165 -0
  38. package/dist/v2/SystemInfo/index.vue +49 -0
  39. package/dist/v2/Tabs/index.vue +127 -0
  40. package/dist/v2/Tag/index.vue +91 -0
  41. package/dist/v2/UniEvent/UniEventItem.vue +157 -0
  42. package/dist/v2/UniEvent/index.vue +127 -0
  43. package/dist/v2/UploadList/UploadDetail.vue +204 -0
  44. package/dist/v2/UploadList/UploadItem.vue +134 -0
  45. package/dist/v2/UploadList/index.vue +143 -0
  46. package/dist/v2/VirtualList/index.vue +140 -0
  47. package/dist/v2/VirtualListPro/AutoSize.vue +50 -0
  48. package/dist/v2/VirtualListPro/index.vue +255 -0
  49. package/dist/v2/VirtualListPro/readme.md +40 -0
  50. package/dist/v2/VuexList/index.vue +80 -0
  51. package/dist/v2/WebSocket/WebSocketItem.vue +129 -0
  52. package/dist/v2/WebSocket/WebSocketList.vue +183 -0
  53. package/dist/v2/WebSocket/index.vue +155 -0
  54. package/dist/v2/WindowInfo/index.vue +49 -0
  55. package/dist/v3/AppInfo/index.vue +35 -0
  56. package/dist/v3/AutoSizer/index.vue +193 -0
  57. package/dist/v3/AutoSizer/index1.vue +186 -0
  58. package/dist/v3/AutoSizer/utils.ts +49 -0
  59. package/dist/v3/CaptureScreen/index.vue +62 -0
  60. package/dist/v3/CloseButton/index.vue +29 -0
  61. package/dist/v3/Connection/index.vue +88 -0
  62. package/dist/v3/ConsoleList/ConsoleItem.vue +208 -0
  63. package/dist/v3/ConsoleList/RunJSInput.vue +240 -0
  64. package/dist/v3/ConsoleList/index.vue +139 -0
  65. package/dist/v3/ConsoleList/staticTips.ts +1145 -0
  66. package/dist/v3/DevTool/index.vue +217 -0
  67. package/dist/v3/DevToolButton/index.vue +210 -0
  68. package/dist/v3/DevToolTitle/index.vue +21 -0
  69. package/dist/v3/DevToolWindow/index.vue +1116 -0
  70. package/dist/v3/DeviceInfo/index.vue +32 -0
  71. package/dist/v3/Empty/empty.png +0 -0
  72. package/dist/v3/Empty/index.vue +28 -0
  73. package/dist/v3/FilterInput/index.vue +87 -0
  74. package/dist/v3/JsonPretty/components/Brackets/index.vue +23 -0
  75. package/dist/v3/JsonPretty/components/Carets/index.vue +59 -0
  76. package/dist/v3/JsonPretty/components/CheckController/index.vue +125 -0
  77. package/dist/v3/JsonPretty/components/TreeNode/index.vue +349 -0
  78. package/dist/v3/JsonPretty/hooks/useClipboard.ts +21 -0
  79. package/dist/v3/JsonPretty/hooks/useError.ts +21 -0
  80. package/dist/v3/JsonPretty/index.vue +476 -0
  81. package/dist/v3/JsonPretty/type.ts +125 -0
  82. package/dist/v3/JsonPretty/utils/index.ts +172 -0
  83. package/dist/v3/NetworkList/NetworkDetail.vue +194 -0
  84. package/dist/v3/NetworkList/NetworkItem.vue +120 -0
  85. package/dist/v3/NetworkList/index.vue +128 -0
  86. package/dist/v3/PiniaList/index.vue +64 -0
  87. package/dist/v3/RouteList/index.vue +121 -0
  88. package/dist/v3/RunJS/index.vue +128 -0
  89. package/dist/v3/SettingList/index.vue +313 -0
  90. package/dist/v3/SourceCode/index.vue +231 -0
  91. package/dist/v3/StorageList/index.vue +170 -0
  92. package/dist/v3/SystemInfo/index.vue +34 -0
  93. package/dist/v3/Tabs/index.vue +123 -0
  94. package/dist/v3/Tag/index.vue +89 -0
  95. package/dist/v3/UniEvent/UniEventItem.vue +126 -0
  96. package/dist/v3/UniEvent/index.vue +98 -0
  97. package/dist/v3/UploadList/UploadDetail.vue +192 -0
  98. package/dist/v3/UploadList/UploadItem.vue +117 -0
  99. package/dist/v3/UploadList/index.vue +117 -0
  100. package/dist/v3/VirtualList/index.vue +112 -0
  101. package/dist/v3/VirtualListPro/AutoSize.vue +43 -0
  102. package/dist/v3/VirtualListPro/index.vue +238 -0
  103. package/dist/v3/VirtualListPro/readme.md +40 -0
  104. package/dist/v3/VuexList/index.vue +54 -0
  105. package/dist/v3/WebSocket/WebSocketItem.vue +103 -0
  106. package/dist/v3/WebSocket/WebSocketList.vue +161 -0
  107. package/dist/v3/WebSocket/index.vue +124 -0
  108. package/dist/v3/WindowInfo/index.vue +33 -0
  109. package/package.json +1 -1
@@ -0,0 +1,143 @@
1
+ <template>
2
+ <view class="upload-content">
3
+ <view class="upload-control">
4
+ <FilterInput
5
+ :modelValue="modelValue"
6
+ placeholder="查询url"
7
+ @search="handleSearch"
8
+ @update:modelValue="handleUpdateModelValue"
9
+ />
10
+ <Tag
11
+ v-for="item in uploadFilterItems"
12
+ :mode="item.mode"
13
+ :key="item.value"
14
+ :active="item.value === currentUploadType"
15
+ @click="onChoose(item.value)"
16
+ >
17
+ {{ item.label }}
18
+ </Tag>
19
+ </view>
20
+ <VirtualListPro
21
+ :dataSource="uploadList"
22
+ :pageSize="15"
23
+ :height="height"
24
+ className="upload-list"
25
+ >
26
+ <template v-slot="{ list, start }">
27
+ <AutoSize
28
+ v-for="(item, index) in list"
29
+ :index="start + index"
30
+ :key="start + index"
31
+ >
32
+ <UploadItem :upload="item" :zIndex="zIndex" />
33
+ </AutoSize>
34
+ <Empty v-if="!uploadList || uploadList.length === 0" />
35
+ </template>
36
+ </VirtualListPro>
37
+ </view>
38
+ </template>
39
+
40
+ <script>
41
+ import Tag from '../Tag/index.vue';
42
+ import UploadItem from './UploadItem.vue';
43
+ import Empty from '../Empty/index.vue';
44
+ import FilterInput from '../FilterInput/index.vue';
45
+ import VirtualListPro from '../VirtualListPro/index.vue';
46
+ import AutoSize from '../VirtualListPro/AutoSize.vue';
47
+
48
+ export default {
49
+ components: {
50
+ Tag,
51
+ UploadItem,
52
+ Empty,
53
+ FilterInput,
54
+ VirtualListPro,
55
+ AutoSize,
56
+ },
57
+ props: {
58
+ currentUploadType: {
59
+ type: String,
60
+ required: true,
61
+ },
62
+ uploadList: {
63
+ type: Array,
64
+ default: () => [],
65
+ },
66
+ modelValue: {
67
+ type: String,
68
+ default: '',
69
+ },
70
+ zIndex: {
71
+ type: Number,
72
+ default: 0,
73
+ },
74
+ },
75
+ data() {
76
+ return {
77
+ height: 0,
78
+ uploadFilterItems: [
79
+ {
80
+ label: '全部',
81
+ value: 'all',
82
+ mode: 'all',
83
+ },
84
+ {
85
+ label: 'pending',
86
+ value: 'pending',
87
+ mode: 'info',
88
+ },
89
+ {
90
+ label: 'success',
91
+ value: 'success',
92
+ mode: 'success',
93
+ },
94
+ {
95
+ label: 'error',
96
+ value: 'error',
97
+ mode: 'error',
98
+ },
99
+ {
100
+ label: '清除',
101
+ value: 'clear',
102
+ mode: 'clear',
103
+ },
104
+ ],
105
+ };
106
+ },
107
+ mounted() {
108
+ const { windowHeight } = uni.getWindowInfo();
109
+ this.height = windowHeight - 32 - 32;
110
+ },
111
+ methods: {
112
+ onChoose(type) {
113
+ this.$emit('choose', type);
114
+ },
115
+ handleSearch(value) {
116
+ this.$emit('search', value);
117
+ },
118
+ handleUpdateModelValue(value) {
119
+ this.$emit('update:modelValue', value);
120
+ },
121
+ },
122
+ };
123
+ </script>
124
+
125
+ <style scoped>
126
+ .upload-content {
127
+ height: 100%;
128
+ font-size: var(--dev-tool-base-font-size);
129
+ }
130
+ .upload-list {
131
+ height: calc(100% - 32px);
132
+ }
133
+ .upload-control {
134
+ display: flex;
135
+ align-items: center;
136
+ justify-content: space-between;
137
+ gap: 8px;
138
+ padding: 0 16px;
139
+ height: 32px;
140
+ border-bottom: 1px solid var(--dev-tool-border-color);
141
+ box-sizing: border-box;
142
+ }
143
+ </style>
@@ -0,0 +1,140 @@
1
+ <template>
2
+ <scroll-view
3
+ v-if="autoVirtual"
4
+ scroll-y
5
+ class="virtual-list"
6
+ :style="{
7
+ height: `${height}px`,
8
+ }"
9
+ @scroll="onVirtualScroll"
10
+ >
11
+ <view
12
+ class="virtual-list-holder"
13
+ :style="{
14
+ height: `${data.length * itemHeight}px`,
15
+ }"
16
+ >
17
+ <view
18
+ class="virtual-list-holder-inner"
19
+ :style="{
20
+ transform: `translateY(${translateY}px)`,
21
+ }"
22
+ >
23
+ <slot :list="visibleData"></slot>
24
+ </view>
25
+ </view>
26
+ </scroll-view>
27
+ <view
28
+ v-else
29
+ class="normal-list"
30
+ :style="{
31
+ height: `${height}px`,
32
+ }"
33
+ >
34
+ <slot :list="visibleData"></slot>
35
+ </view>
36
+ </template>
37
+
38
+ <script>
39
+ export default {
40
+ props: {
41
+ /** 虚拟列表高度 */
42
+ height: {
43
+ type: Number,
44
+ required: true,
45
+ },
46
+ /** 每一项高度 */
47
+ itemHeight: {
48
+ type: Number,
49
+ required: true,
50
+ },
51
+ /** 渲染的数据列表 */
52
+ dataSource: {
53
+ type: Array,
54
+ default: () => [],
55
+ },
56
+ /** 虚拟列表自动开启行数 */
57
+ autoVirtualRow: {
58
+ type: Number,
59
+ default: 0,
60
+ },
61
+ },
62
+ data() {
63
+ return {
64
+ translateY: 0,
65
+ visibleData: [],
66
+ scrollTop: 0,
67
+ };
68
+ },
69
+ computed: {
70
+ autoVirtual() {
71
+ if (typeof this.autoVirtualRow === 'number') {
72
+ return this.data.length > this.autoVirtualRow;
73
+ }
74
+ return true;
75
+ },
76
+ },
77
+ watch: {
78
+ data: {
79
+ handler() {
80
+ this.updateVisibleData(this.scrollTop);
81
+ },
82
+ deep: true,
83
+ },
84
+ height() {
85
+ this.updateVisibleData(this.scrollTop);
86
+ },
87
+ itemHeight() {
88
+ this.updateVisibleData(this.scrollTop);
89
+ },
90
+ },
91
+ mounted() {
92
+ this.updateVisibleData();
93
+ },
94
+ methods: {
95
+ onVirtualScroll(e) {
96
+ const scrollTop = e?.detail?.scrollTop ?? 0;
97
+ this.scrollTop = scrollTop;
98
+ this.updateVisibleData(scrollTop);
99
+ },
100
+ updateVisibleData(scrollTop = 0) {
101
+ const flatDataValue = this.data || [];
102
+ if (this.autoVirtual) {
103
+ const visibleCount = Math.ceil(this.height / this.itemHeight);
104
+ const scrollCount = Math.floor(scrollTop / this.itemHeight);
105
+ // 计算可视区域的起始索引
106
+ let start = Math.max(0, scrollCount);
107
+ // 确保结束索引不超过数据总长度
108
+ let end = Math.min(start + visibleCount, flatDataValue.length);
109
+ // 修正可视区域数据
110
+ this.visibleData = flatDataValue.slice(start, end);
111
+ // 计算偏移量
112
+ this.translateY = start * this.itemHeight;
113
+ } else {
114
+ // 非虚拟列表模式显示全部数据
115
+ this.visibleData = flatDataValue;
116
+ this.translateY = 0;
117
+ }
118
+ },
119
+ },
120
+ };
121
+ </script>
122
+
123
+ <style scoped>
124
+ .normal-list,
125
+ .virtual-list {
126
+ position: relative;
127
+ width: 100%;
128
+ overflow: auto;
129
+ }
130
+
131
+ .virtual-list-holder {
132
+ position: relative;
133
+ }
134
+
135
+ .virtual-list-holder-inner {
136
+ position: absolute;
137
+ width: 100%;
138
+ transition: transform 0.1s ease-out;
139
+ }
140
+ </style>
@@ -0,0 +1,50 @@
1
+ <template>
2
+ <view :class="className">
3
+ <slot></slot>
4
+ </view>
5
+ </template>
6
+
7
+ <script>
8
+ import { uniqueId } from '../../utils';
9
+
10
+ export default {
11
+ props: {
12
+ index: {
13
+ type: Number,
14
+ required: true,
15
+ },
16
+ },
17
+ data() {
18
+ return {
19
+ className: uniqueId('virtual-'),
20
+ };
21
+ },
22
+ inject: ['itemsHeight', 'onSizeChange'],
23
+ mounted() {
24
+ // 获取父组件注入的方法和数据(Vue2 通过 $parent 或 provide/inject 兼容实现)
25
+ const onSizeChange = this?.onSizeChange;
26
+ const itemsHeight = this?.itemsHeight;
27
+
28
+ // 如果已有高度则不重复计算
29
+ if (Array.isArray(itemsHeight) && itemsHeight[this.index] !== undefined) {
30
+ return;
31
+ }
32
+
33
+ this.$nextTick(() => {
34
+ // Vue2 中的选择器查询
35
+ const query = uni.createSelectorQuery().in(this);
36
+ query
37
+ .select('.' + this.className)
38
+ .boundingClientRect((rect) => {
39
+ if (Array.isArray(rect)) return;
40
+ if (typeof onSizeChange === 'function') {
41
+ onSizeChange(this.index, rect?.height ?? 0);
42
+ }
43
+ })
44
+ .exec();
45
+ });
46
+ },
47
+ };
48
+ </script>
49
+
50
+ <style scoped></style>
@@ -0,0 +1,255 @@
1
+ <template>
2
+ <scroll-view
3
+ :lower-threshold="preLodeHeight"
4
+ :scroll-with-animation="scrollWithAnimation"
5
+ :class="['virtual-list', className]"
6
+ :style="style"
7
+ :scroll-into-view="innerScrollIntoView"
8
+ scroll-y
9
+ @scroll="onScroll"
10
+ @scrolltolower="onScrollToLower"
11
+ >
12
+ <!-- 阈值判断 -->
13
+ <view :id="placeholderId" :style="{ height: `${currentHeight}px` }"></view>
14
+ <view>
15
+ <!-- 将可视数据传入到slot -->
16
+ <slot :list="visitableData" :current="current" :start="start"></slot>
17
+ </view>
18
+
19
+ <view
20
+ v-if="currentHeight > height && showBackTop"
21
+ class="virtual-back-top"
22
+ @click="onBackTop"
23
+ >
24
+
25
+ </view>
26
+ </scroll-view>
27
+ </template>
28
+
29
+ <script>
30
+ import { uniqueId } from '../../utils';
31
+
32
+ export default {
33
+ props: {
34
+ /** 渲染数据 */
35
+ dataSource: {
36
+ type: Array,
37
+ required: true,
38
+ default: () => [],
39
+ },
40
+ /** 虚拟列表高度 */
41
+ height: {
42
+ type: Number,
43
+ default: 400,
44
+ },
45
+ /** 分页大小 */
46
+ pageSize: {
47
+ type: Number,
48
+ default: 10,
49
+ },
50
+ /** 预加载高度 */
51
+ preLodeHeight: {
52
+ type: Number,
53
+ default: 50,
54
+ },
55
+ /** 类名 */
56
+ className: {
57
+ type: String,
58
+ default: '',
59
+ },
60
+ /** 滚动到指定元素 */
61
+ scrollIntoView: {
62
+ type: String,
63
+ default: '',
64
+ },
65
+ /** 滚动动画 */
66
+ scrollWithAnimation: {
67
+ type: Boolean,
68
+ default: false,
69
+ },
70
+ /** 显示返回顶部按钮 */
71
+ showBackTop: {
72
+ type: Boolean,
73
+ default: false,
74
+ },
75
+ },
76
+ data() {
77
+ return {
78
+ // 生成唯一占位符ID
79
+ placeholderId: uniqueId('virtual-placeholder-'),
80
+ // 子项高度数组
81
+ itemsHeight: [],
82
+ // 响应式状态
83
+ current: 1, // 当前页码
84
+ visitableData: [], // 可视区域数据
85
+ currentHeight: 0, // 当前总高度
86
+ scrollTop: 0, // 滚动位置
87
+
88
+ toView: '', // 内部滚动目标
89
+ start: 0,
90
+ };
91
+ },
92
+ computed: {
93
+ // 计算列表样式
94
+ style() {
95
+ return {
96
+ height:
97
+ typeof this.height === 'string' ? this.height : `${this.height}px`,
98
+ };
99
+ },
100
+ // 内部滚动目标
101
+ innerScrollIntoView() {
102
+ return this.toView || this.scrollIntoView;
103
+ },
104
+ },
105
+ watch: {
106
+ // 监听数据和分页大小变化,重置列表
107
+ dataSource: {
108
+ handler(val) {
109
+ this.resetList();
110
+ },
111
+ deep: true,
112
+ },
113
+ pageSize() {
114
+ this.resetList();
115
+ },
116
+ },
117
+ created() {
118
+ // 初始渲染数据(前两页)
119
+ this.visitableData = this.dataSource.slice(0, this.pageSize * 2);
120
+ },
121
+ provide() {
122
+ return {
123
+ itemsHeight: this.itemsHeight,
124
+ onSizeChange: this.onSizeChange,
125
+ };
126
+ },
127
+ methods: {
128
+ // 重置列表数据
129
+ resetList() {
130
+ this.current = 1;
131
+ this.start = 0;
132
+ this.visitableData = this.dataSource.slice(0, this.pageSize * 2);
133
+ this.itemsHeight = [];
134
+ this.currentHeight = 0;
135
+ },
136
+ // 滚动事件处理
137
+ onScroll(e) {
138
+ const scrollTop = e.detail.scrollTop;
139
+ this.scrollTop = scrollTop;
140
+
141
+ // 向上滚动时加载前面的数据
142
+ if (
143
+ this.current > 1 &&
144
+ this.currentHeight > 0 &&
145
+ scrollTop - this.preLodeHeight < this.currentHeight
146
+ ) {
147
+ this.start = this.current * this.pageSize;
148
+ this.current--;
149
+
150
+ this.updateVisitableData('up');
151
+ this.updateCurrentHeight();
152
+ }
153
+ },
154
+ // 滚动到底部加载更多
155
+ onScrollToLower() {
156
+ if ((this.current + 1) * this.pageSize < this.dataSource.length) {
157
+ this.start = this.current * this.pageSize;
158
+ this.current++;
159
+
160
+ this.updateCurrentHeight();
161
+ this.$nextTick(() => {
162
+ this.updateVisitableData('down');
163
+ });
164
+ }
165
+ },
166
+ // 更新可视区域数据
167
+ updateVisitableData(direction) {
168
+ let tempList = [...this.visitableData];
169
+ const pageSize = this.pageSize;
170
+ const current = this.current;
171
+
172
+ if (direction === 'down') {
173
+ // 向下滚动:移除最前面的一页,添加新的一页
174
+ tempList.splice(0, pageSize);
175
+ const start = pageSize * current;
176
+ let end = pageSize * (current + 1);
177
+ end = end > this.dataSource.length ? this.dataSource.length : end;
178
+ const newData = this.dataSource.slice(start, end);
179
+ tempList.push(...newData);
180
+ } else {
181
+ // 向上滚动:移除最后面的多余数据,添加前面的一页
182
+ // 将最末尾的部分进行隐藏
183
+ const delCount =
184
+ tempList.length - pageSize > 0
185
+ ? pageSize
186
+ : tempList.length - pageSize;
187
+
188
+ tempList.splice(pageSize, delCount);
189
+
190
+ // 处理上一页内容
191
+ let start = pageSize * (current - 1);
192
+
193
+ start = start < 0 ? 0 : start;
194
+
195
+ const end = pageSize * current;
196
+
197
+ if (end < 0) return;
198
+
199
+ const newData = this.dataSource.slice(start, end);
200
+ tempList.unshift(...newData);
201
+ }
202
+
203
+ this.visitableData = tempList;
204
+ },
205
+ // 更新总高度(累加已加载项的高度)
206
+ updateCurrentHeight() {
207
+ const total = this.itemsHeight
208
+ .slice(0, (this.current - 1) * this.pageSize)
209
+ .reduce((acc, height) => acc + (height || 0), 0);
210
+ this.currentHeight = total;
211
+ },
212
+ // 接收子组件的高度更新
213
+ onSizeChange(index, height) {
214
+ const list = [...this.itemsHeight];
215
+ list[index] = height;
216
+ this.itemsHeight = [...list];
217
+ },
218
+ // 返回顶部
219
+ onBackTop() {
220
+ this.toView = this.placeholderId;
221
+ this.$nextTick(() => {
222
+ this.current = 1;
223
+ this.start = 0;
224
+ this.currentHeight = 0;
225
+ this.updateVisitableData('up');
226
+ // 重置滚动目标,避免下次滚动冲突
227
+ this.toView = '';
228
+ });
229
+ },
230
+ },
231
+ };
232
+ </script>
233
+
234
+ <style scoped>
235
+ .virtual-list {
236
+ position: relative;
237
+ overflow: auto;
238
+ }
239
+
240
+ .virtual-back-top {
241
+ position: sticky;
242
+ bottom: 20px;
243
+ left: 80%;
244
+ display: flex;
245
+ align-items: center;
246
+ justify-content: center;
247
+ width: 40px;
248
+ height: 40px;
249
+ box-shadow: 0 0 5px rgba(0, 0, 0, 0.2);
250
+ border-radius: 50%;
251
+ background: #fff;
252
+ cursor: pointer;
253
+ z-index: 10;
254
+ }
255
+ </style>
@@ -0,0 +1,40 @@
1
+ # VirtualListAutoHeight
2
+
3
+ 自适应高度虚拟列表
4
+
5
+ ## 核心
6
+
7
+ - 初始加载两页数据
8
+ - 初始获取当前加载的渲染列表的数据 ,得到第一页高度
9
+ - scroll-view
10
+ - 滚动到底部(顶部)current + 1
11
+ - createIntersectionObserver
12
+ - 辅助反向监听节点是否出现再可视范围之内
13
+ - current - 1
14
+ - 数据分页之后确定每页高度,采用合并高度支撑滚动条
15
+ - 合并高度计算逻辑: 第一页高度 = 第一页高度
16
+ - 后续页高度 = 前面所有高度 + 当前页高度.
17
+
18
+
19
+ 一页两条
20
+
21
+ pageSize = 2
22
+ current = 2
23
+ visibleDate = [3,4,5,6]
24
+
25
+ visibleDate.splice(1*2, visibleDate.length - 1*2)
26
+
27
+ const start = cur
28
+
29
+
30
+ 1
31
+ 2
32
+
33
+ 3
34
+ 4
35
+
36
+ 5
37
+ 6
38
+
39
+ current = 1
40
+ visibleDate = [1,2,3,4]
@@ -0,0 +1,80 @@
1
+ <template>
2
+ <view class="vuex-content">
3
+ <JsonPretty
4
+ :data="vuexList"
5
+ showLength
6
+ editable
7
+ v-if="showJson"
8
+ @update:data="onUpdateData"
9
+ @nodeClick="onNodeClick"
10
+ />
11
+ <Empty v-else />
12
+ </view>
13
+ </template>
14
+
15
+ <script>
16
+ import JsonPretty from '../JsonPretty/index.vue';
17
+ import Empty from '../Empty/index.vue';
18
+
19
+ export default {
20
+ components: {
21
+ JsonPretty,
22
+ Empty,
23
+ },
24
+ props: {
25
+ vuexList: {
26
+ type: Object,
27
+ required: true,
28
+ default: () => ({}),
29
+ },
30
+ },
31
+ data() {
32
+ return {
33
+ currentSelect: null, // 记录当前点击的节点
34
+ };
35
+ },
36
+ computed: {
37
+ // 判断是否显示JSON视图
38
+ showJson() {
39
+ try {
40
+ const str = JSON.stringify(this.vuexList);
41
+ // 当数据为对象且不为空时显示
42
+ return (
43
+ typeof this.vuexList === 'object' &&
44
+ this.vuexList !== null &&
45
+ str !== '{}' &&
46
+ str !== ''
47
+ );
48
+ } catch (error) {
49
+ return false;
50
+ }
51
+ },
52
+ },
53
+ methods: {
54
+ // 更新数据时触发
55
+ onUpdateData(data) {
56
+ // 解析当前选中节点的第一个键名
57
+ const firstKey = this.currentSelect?.path?.split('.')?.slice(1)?.[0];
58
+ // 触发更新事件
59
+ this.$emit('update:vuexList', data);
60
+ // 触发差异值事件
61
+ if (firstKey) {
62
+ this.$emit('diffValue', {
63
+ [firstKey]: data[firstKey],
64
+ });
65
+ }
66
+ },
67
+ // 节点点击事件
68
+ onNodeClick(node) {
69
+ this.currentSelect = node;
70
+ },
71
+ },
72
+ };
73
+ </script>
74
+
75
+ <style scoped>
76
+ .vuex-content {
77
+ padding: 16px;
78
+ font-size: var(--dev-tool-base-font-size);
79
+ }
80
+ </style>