vite-uni-dev-tool 0.0.9 → 0.0.11
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/README.md +18 -0
- package/dev/components/AppInfo/index.vue +36 -0
- package/dev/components/AutoSizer/index.vue +193 -0
- package/dev/components/AutoSizer/index1.vue +186 -0
- package/dev/components/AutoSizer/utils.ts +49 -0
- package/dev/components/CaptureScreen/index.vue +62 -0
- package/dev/components/Code/index.vue +7 -4
- package/dev/components/ConsoleList/RunJSInput.vue +177 -1
- package/dev/components/ConsoleList/index.vue +29 -19
- package/dev/components/ConsoleList/staticTips.ts +1145 -0
- package/dev/components/DevToolWindow/index.vue +225 -101
- package/dev/components/JsonPretty/components/Carets/index.vue +10 -14
- package/dev/components/JsonPretty/index.vue +50 -41
- package/dev/components/NetworkList/index.vue +16 -9
- package/dev/components/RouteList/index.vue +31 -19
- package/dev/components/Tabs/index.vue +23 -10
- package/dev/components/UploadList/index.vue +15 -5
- package/dev/components/VirtualListPro/AutoSize.vue +43 -0
- package/dev/components/VirtualListPro/index.vue +175 -0
- package/dev/components/VirtualListPro/readme.md +40 -0
- package/dev/components/WebSocket/index.vue +16 -4
- package/dev/const.ts +2 -4
- package/dev/devEvent/index.ts +29 -2
- package/dev/devIntercept/index.ts +18 -0
- package/dev/devStore/index.ts +33 -0
- package/dev/plugins/uniDevTool/uniDevTool.js +36 -36
- package/dev/plugins/uniGlobalComponents/uniGlobalComponents.js +7 -7
- package/dev/type.ts +7 -0
- package/dev/utils/array.ts +15 -0
- package/dev/utils/index.ts +3 -0
- package/dev/utils/string.ts +12 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -151,6 +151,24 @@ uni.__dev__console.log('hello vite-uni-dev-tool');
|
|
|
151
151
|
|
|
152
152
|
## 更新日志
|
|
153
153
|
|
|
154
|
+
### 0.0.11
|
|
155
|
+
|
|
156
|
+
- 新增 console run 简易提示
|
|
157
|
+
- 新增 appInfo
|
|
158
|
+
- 新增 captureScreen(h5端不支持)
|
|
159
|
+
- 新增滑动切换
|
|
160
|
+
- 修复 console 滚动到指定位置
|
|
161
|
+
- 修复调用栈起始行
|
|
162
|
+
- 修复 json pretty 折叠icon
|
|
163
|
+
|
|
164
|
+
### 0.0.10
|
|
165
|
+
|
|
166
|
+
- 修复 console 过滤异常
|
|
167
|
+
|
|
168
|
+
### 0.0.9
|
|
169
|
+
|
|
170
|
+
- 修复 template 多节点造成的 createIntersectionObserver 异常
|
|
171
|
+
|
|
154
172
|
### 0.0.8
|
|
155
173
|
|
|
156
174
|
- 修复多 template 注入调试工具异常
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<view class="app-info-content">
|
|
3
|
+
<JsonPretty v-if="showJson" :data="appInfo" />
|
|
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
|
+
|
|
11
|
+
import Empty from '../Empty/index.vue';
|
|
12
|
+
const props = defineProps<{
|
|
13
|
+
appInfo: Record<string, any>;
|
|
14
|
+
}>();
|
|
15
|
+
|
|
16
|
+
const showJson = computed(() => {
|
|
17
|
+
try {
|
|
18
|
+
const str = JSON.stringify(props.appInfo);
|
|
19
|
+
if (typeof props.appInfo === 'object' && (str === '' || str === '{}')) {
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
return true;
|
|
23
|
+
} catch (error) {
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
</script>
|
|
28
|
+
<style scoped>
|
|
29
|
+
.app-info-content {
|
|
30
|
+
padding: 16px;
|
|
31
|
+
font-size: var(--dev-tool-base-font-size);
|
|
32
|
+
|
|
33
|
+
height: calc(100% - 32px);
|
|
34
|
+
overflow: auto;
|
|
35
|
+
}
|
|
36
|
+
</style>
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<view class="auto-sizer">
|
|
3
|
+
<!-- 大小和slot 内容宽度一致 -->
|
|
4
|
+
<view class="listener-slot">
|
|
5
|
+
<slot></slot>
|
|
6
|
+
</view>
|
|
7
|
+
|
|
8
|
+
<!-- 变大监听固定在 listener-slot 右下角大1px位置 变大时 相交触发监听 -->
|
|
9
|
+
<view
|
|
10
|
+
class="anchor-height-add"
|
|
11
|
+
:style="{
|
|
12
|
+
top: listenerSlot.height + 1 + 'px',
|
|
13
|
+
}"
|
|
14
|
+
>
|
|
15
|
+
</view>
|
|
16
|
+
|
|
17
|
+
<!-- 变小监听固定在 listener-slot 右下角小1px位置 减小时 离开触发监听 -->
|
|
18
|
+
<view
|
|
19
|
+
class="anchor-height-sub"
|
|
20
|
+
:style="{
|
|
21
|
+
top: listenerSlot.height - 1 + 'px',
|
|
22
|
+
}"
|
|
23
|
+
>
|
|
24
|
+
</view>
|
|
25
|
+
|
|
26
|
+
<!-- 变大监听固定在 listener-slot 右下角大1px位置 变大时 相交触发监听 -->
|
|
27
|
+
<view
|
|
28
|
+
class="anchor-width-add"
|
|
29
|
+
:style="{
|
|
30
|
+
left: listenerSlot.width + 1 + 'px',
|
|
31
|
+
top: '0px',
|
|
32
|
+
}"
|
|
33
|
+
>
|
|
34
|
+
</view>
|
|
35
|
+
|
|
36
|
+
<!-- 变小监听固定在 listener-slot 右下角小1px位置 减小时 离开触发监听 -->
|
|
37
|
+
<view
|
|
38
|
+
class="anchor-width-sub"
|
|
39
|
+
:style="{
|
|
40
|
+
left: listenerSlot.width - 1 + 'px',
|
|
41
|
+
top: '0px',
|
|
42
|
+
}"
|
|
43
|
+
>
|
|
44
|
+
</view>
|
|
45
|
+
</view>
|
|
46
|
+
</template>
|
|
47
|
+
<script lang="ts" setup>
|
|
48
|
+
import {
|
|
49
|
+
getCurrentInstance,
|
|
50
|
+
onMounted,
|
|
51
|
+
inject,
|
|
52
|
+
reactive,
|
|
53
|
+
onUnmounted,
|
|
54
|
+
} from 'vue';
|
|
55
|
+
import { debounce } from '../../utils';
|
|
56
|
+
|
|
57
|
+
type Size = {
|
|
58
|
+
width: number;
|
|
59
|
+
height: number;
|
|
60
|
+
top: number;
|
|
61
|
+
left: number;
|
|
62
|
+
right: number;
|
|
63
|
+
bottom: number;
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
const props = defineProps<{
|
|
67
|
+
index: number;
|
|
68
|
+
immediate?: boolean;
|
|
69
|
+
}>();
|
|
70
|
+
|
|
71
|
+
const emit = defineEmits<{ (e: 'resize', size: Size): void }>();
|
|
72
|
+
|
|
73
|
+
let isMounted = false;
|
|
74
|
+
|
|
75
|
+
const listenerSlot = reactive({
|
|
76
|
+
width: 0,
|
|
77
|
+
height: 0,
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
const size: Size = {
|
|
81
|
+
width: 0,
|
|
82
|
+
height: 0,
|
|
83
|
+
top: 0,
|
|
84
|
+
left: 0,
|
|
85
|
+
right: 0,
|
|
86
|
+
bottom: 0,
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
const instance = getCurrentInstance();
|
|
90
|
+
|
|
91
|
+
const query = uni.createSelectorQuery().in(instance);
|
|
92
|
+
|
|
93
|
+
const onSizeChange =
|
|
94
|
+
inject<(index: number, height: number) => void>('onSizeChange');
|
|
95
|
+
|
|
96
|
+
/** 外界记录的高度 */
|
|
97
|
+
const itemsHeight = inject<number[]>('itemsHeight');
|
|
98
|
+
|
|
99
|
+
const debounceReact = debounce(
|
|
100
|
+
(rect: UniApp.NodeInfo | UniApp.NodeInfo[]) => {
|
|
101
|
+
if (Array.isArray(rect)) return;
|
|
102
|
+
|
|
103
|
+
// 获取屏幕尺寸
|
|
104
|
+
const { windowWidth, windowHeight } = uni.getSystemInfoSync();
|
|
105
|
+
|
|
106
|
+
// 在尺寸更新时限制最大值
|
|
107
|
+
listenerSlot.height = Math.min(rect.height ?? 0, windowHeight);
|
|
108
|
+
listenerSlot.width = Math.min(rect.width ?? 0, windowWidth);
|
|
109
|
+
|
|
110
|
+
onSizeChange?.(props.index, rect.height ?? 0);
|
|
111
|
+
|
|
112
|
+
size.width = rect.width ?? 0;
|
|
113
|
+
size.height = rect.height ?? 0;
|
|
114
|
+
size.top = rect.top ?? 0;
|
|
115
|
+
size.left = rect.left ?? 0;
|
|
116
|
+
size.right = rect.right ?? 0;
|
|
117
|
+
size.bottom = rect.bottom ?? 0;
|
|
118
|
+
|
|
119
|
+
if (props.immediate && !isMounted) {
|
|
120
|
+
emit('resize', size);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
if (isMounted) {
|
|
124
|
+
emit('resize', size);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
isMounted = true;
|
|
128
|
+
},
|
|
129
|
+
100,
|
|
130
|
+
true,
|
|
131
|
+
);
|
|
132
|
+
function getSize() {
|
|
133
|
+
query.select('.listener-slot').boundingClientRect(debounceReact).exec();
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
const debounceGetSize = debounce(getSize, 100, true);
|
|
137
|
+
|
|
138
|
+
let observer: UniNamespace.IntersectionObserver;
|
|
139
|
+
onMounted(() => {
|
|
140
|
+
// 防止重复获取
|
|
141
|
+
// TODO
|
|
142
|
+
// if (itemsHeight && itemsHeight?.[props.index]) return;
|
|
143
|
+
|
|
144
|
+
// 初始大小
|
|
145
|
+
debounceGetSize();
|
|
146
|
+
|
|
147
|
+
// TODO 只有可视范围之内才获取大小
|
|
148
|
+
observer = uni.createIntersectionObserver(instance, { thresholds: [0, 1] });
|
|
149
|
+
// 变大监听
|
|
150
|
+
observer
|
|
151
|
+
.relativeTo('.auto-sizer')
|
|
152
|
+
.observe('.anchor-height-add', debounceGetSize);
|
|
153
|
+
// 变小监听
|
|
154
|
+
observer
|
|
155
|
+
.relativeTo('.auto-sizer')
|
|
156
|
+
.observe('.anchor-height-sub', debounceGetSize);
|
|
157
|
+
|
|
158
|
+
// 变大监听
|
|
159
|
+
observer
|
|
160
|
+
.relativeTo('.auto-sizer')
|
|
161
|
+
.observe('.anchor-width-add', debounceGetSize);
|
|
162
|
+
// 变小监听
|
|
163
|
+
observer
|
|
164
|
+
.relativeTo('.auto-sizer')
|
|
165
|
+
.observe('.anchor-width-sub', debounceGetSize);
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
onUnmounted(() => {
|
|
169
|
+
// 销毁监听
|
|
170
|
+
observer.disconnect();
|
|
171
|
+
});
|
|
172
|
+
</script>
|
|
173
|
+
|
|
174
|
+
<style scoped>
|
|
175
|
+
.auto-sizer {
|
|
176
|
+
position: relative;
|
|
177
|
+
overflow: hidden;
|
|
178
|
+
width: min-content;
|
|
179
|
+
height: min-content;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
.anchor-height-add,
|
|
183
|
+
.anchor-height-sub,
|
|
184
|
+
.anchor-width-add,
|
|
185
|
+
.anchor-width-sub {
|
|
186
|
+
position: absolute;
|
|
187
|
+
width: 1px;
|
|
188
|
+
height: 1px;
|
|
189
|
+
|
|
190
|
+
background-color: skyblue;
|
|
191
|
+
visibility: hidden;
|
|
192
|
+
}
|
|
193
|
+
</style>
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<view
|
|
3
|
+
class="l-resize l-class"
|
|
4
|
+
:class="{ 'l-resize-target': hasNoDefaultSlot }"
|
|
5
|
+
:style="[styles, lStyle]"
|
|
6
|
+
>
|
|
7
|
+
<!--插槽需要脱离父容器文档流,防止父容器固宽固高,进而导致插槽大小被被父容器限制-->
|
|
8
|
+
<view
|
|
9
|
+
ref="l-resize__container"
|
|
10
|
+
class="l-resize__container l-container-class"
|
|
11
|
+
:style="[lStyle]"
|
|
12
|
+
>
|
|
13
|
+
<!--被监听的插槽-->
|
|
14
|
+
<slot></slot>
|
|
15
|
+
<!--监听插槽变大-->
|
|
16
|
+
<scroll-view
|
|
17
|
+
class="l-resize__wrapper"
|
|
18
|
+
:scroll-y="true"
|
|
19
|
+
:scroll-x="true"
|
|
20
|
+
:scroll-top="expandScrollTop"
|
|
21
|
+
:scroll-left="expandScrollLeft"
|
|
22
|
+
@scroll="onScrollHandler"
|
|
23
|
+
>
|
|
24
|
+
<view
|
|
25
|
+
class="l-resize__wrapper--placeholder"
|
|
26
|
+
style="height: 100000px; width: 100000px"
|
|
27
|
+
></view>
|
|
28
|
+
</scroll-view>
|
|
29
|
+
<!--监听插槽变小-->
|
|
30
|
+
<scroll-view
|
|
31
|
+
class="l-resize__wrapper"
|
|
32
|
+
:scroll-y="true"
|
|
33
|
+
:scroll-x="true"
|
|
34
|
+
:scroll-top="shrinkScrollTop"
|
|
35
|
+
:scroll-left="shrinkScrollLeft"
|
|
36
|
+
@scroll="onScrollHandler"
|
|
37
|
+
>
|
|
38
|
+
<view
|
|
39
|
+
class="l-resize__wrapper--placeholder"
|
|
40
|
+
style="height: 250%; width: 250%"
|
|
41
|
+
></view>
|
|
42
|
+
</scroll-view>
|
|
43
|
+
</view>
|
|
44
|
+
</view>
|
|
45
|
+
</template>
|
|
46
|
+
<script lang="ts" setup>
|
|
47
|
+
import { ref, onMounted, getCurrentInstance, computed } from 'vue';
|
|
48
|
+
import { getRect, addUnit } from './utils';
|
|
49
|
+
|
|
50
|
+
interface ResizeResult {
|
|
51
|
+
bottom?: number;
|
|
52
|
+
top?: number;
|
|
53
|
+
left?: number;
|
|
54
|
+
right?: number;
|
|
55
|
+
height?: number;
|
|
56
|
+
width?: number;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
defineProps<{
|
|
60
|
+
lStyle?: any;
|
|
61
|
+
}>();
|
|
62
|
+
|
|
63
|
+
const emit = defineEmits(['resize']);
|
|
64
|
+
|
|
65
|
+
const context = getCurrentInstance();
|
|
66
|
+
const width = ref(0);
|
|
67
|
+
const hasNoDefaultSlot = ref(false);
|
|
68
|
+
const height = ref(0);
|
|
69
|
+
const expandScrollTop = ref(0);
|
|
70
|
+
const expandScrollLeft = ref(0);
|
|
71
|
+
const shrinkScrollTop = ref(0);
|
|
72
|
+
const shrinkScrollLeft = ref(0);
|
|
73
|
+
|
|
74
|
+
let scrollEventCount = 0;
|
|
75
|
+
let lastHeight = 0;
|
|
76
|
+
let lastWidth = 0;
|
|
77
|
+
const querySelector = '.l-resize__container';
|
|
78
|
+
let onScrollHandlerClone = () => {
|
|
79
|
+
getRect(querySelector, context).then((res: ResizeResult) => {
|
|
80
|
+
// 前两次滚动事件被触发,说明 created 的修改已渲染,通知用户代码当前容器大小
|
|
81
|
+
if (scrollEventCount++ === 0) {
|
|
82
|
+
resizeEvent(res);
|
|
83
|
+
}
|
|
84
|
+
// 滚动条拉到底部会触发两次多余的事件,屏蔽掉。
|
|
85
|
+
if (scrollEventCount < 3) return;
|
|
86
|
+
// 手动设置父容器高宽,防止父容器坍塌
|
|
87
|
+
// 滚动完,重新获取容器新的高度
|
|
88
|
+
const newHeight = res.height;
|
|
89
|
+
const newWidth = res.width;
|
|
90
|
+
// 立即填充父容器高宽
|
|
91
|
+
height.value = newHeight ?? 0;
|
|
92
|
+
width.value = newWidth ?? 0;
|
|
93
|
+
// 宽高都改变时,只需要触发一次 size 事件
|
|
94
|
+
const emitStack = [];
|
|
95
|
+
if (newHeight !== lastHeight) {
|
|
96
|
+
lastHeight = newHeight ?? 0;
|
|
97
|
+
emitStack.push(1);
|
|
98
|
+
}
|
|
99
|
+
if (newWidth !== lastWidth) {
|
|
100
|
+
lastWidth = newWidth ?? 0;
|
|
101
|
+
emitStack.push(1);
|
|
102
|
+
}
|
|
103
|
+
if (emitStack.length !== 0) {
|
|
104
|
+
resizeEvent(res);
|
|
105
|
+
}
|
|
106
|
+
// 滚动条拉到底部(如果使用 nextTick 效果更佳)
|
|
107
|
+
scrollToBottom({ width: lastWidth, height: lastHeight });
|
|
108
|
+
});
|
|
109
|
+
};
|
|
110
|
+
let onScrollHandler = () => {
|
|
111
|
+
if (onScrollHandlerClone) {
|
|
112
|
+
onScrollHandlerClone();
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
const scrollToBottom = (res: Record<string, number>) => {
|
|
116
|
+
expandScrollTop.value = 100000 + res.height;
|
|
117
|
+
shrinkScrollTop.value = 3 * height.value + res.height;
|
|
118
|
+
expandScrollLeft.value = 100000 + res.width;
|
|
119
|
+
shrinkScrollLeft.value = 3 * width.value + res.width;
|
|
120
|
+
};
|
|
121
|
+
const resizeEvent = (res: ResizeResult) => {
|
|
122
|
+
const result: any = {};
|
|
123
|
+
['bottom', 'top', 'left', 'right', 'height', 'width'].forEach((propName) => {
|
|
124
|
+
result[propName] = res[propName as keyof ResizeResult];
|
|
125
|
+
});
|
|
126
|
+
emit('resize', result);
|
|
127
|
+
};
|
|
128
|
+
const styles = computed(() => {
|
|
129
|
+
if (context && context.slots?.default && (width.value || height.value)) {
|
|
130
|
+
return {
|
|
131
|
+
width: addUnit(width.value),
|
|
132
|
+
height: addUnit(height.value),
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
return {};
|
|
136
|
+
});
|
|
137
|
+
onMounted(() => {
|
|
138
|
+
// const options = { context };
|
|
139
|
+
hasNoDefaultSlot.value = !context?.slots.default;
|
|
140
|
+
getRect(querySelector, context).then((res) => {
|
|
141
|
+
// 闭包记录容器高度
|
|
142
|
+
lastHeight = res.height ?? 0;
|
|
143
|
+
lastWidth = res.width ?? 0;
|
|
144
|
+
// 立即填充父容器高宽
|
|
145
|
+
width.value = lastWidth;
|
|
146
|
+
height.value = lastHeight;
|
|
147
|
+
|
|
148
|
+
scrollToBottom({ width: lastWidth, height: lastHeight });
|
|
149
|
+
});
|
|
150
|
+
});
|
|
151
|
+
</script>
|
|
152
|
+
<style lang="scss" scoped>
|
|
153
|
+
.l-resize {
|
|
154
|
+
&__container {
|
|
155
|
+
position: absolute;
|
|
156
|
+
min-width: 1px;
|
|
157
|
+
min-height: 1px;
|
|
158
|
+
}
|
|
159
|
+
&-target,
|
|
160
|
+
&__wrapper {
|
|
161
|
+
background-color: aqua;
|
|
162
|
+
position: absolute;
|
|
163
|
+
top: 0;
|
|
164
|
+
bottom: 0;
|
|
165
|
+
left: 0;
|
|
166
|
+
right: 0;
|
|
167
|
+
z-index: -9999;
|
|
168
|
+
overflow: hidden;
|
|
169
|
+
|
|
170
|
+
visibility: hidden;
|
|
171
|
+
}
|
|
172
|
+
&-target {
|
|
173
|
+
.l-resize__container {
|
|
174
|
+
width: 100%;
|
|
175
|
+
height: 100%;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
&__wrapper {
|
|
179
|
+
&--placeholder {
|
|
180
|
+
transition: 0s;
|
|
181
|
+
|
|
182
|
+
animation: none;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
</style>
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { ComponentInternalInstance, ComponentPublicInstance } from 'vue';
|
|
2
|
+
|
|
3
|
+
export function getRect(
|
|
4
|
+
selector: string,
|
|
5
|
+
context: ComponentInternalInstance | null | any,
|
|
6
|
+
node: boolean = false,
|
|
7
|
+
) {
|
|
8
|
+
// 之前是个对象,现在改成实例,防止旧版会报错
|
|
9
|
+
if (context == null) {
|
|
10
|
+
return Promise.reject('context is null');
|
|
11
|
+
}
|
|
12
|
+
if (context?.context) {
|
|
13
|
+
context = context.context;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
return new Promise<UniNamespace.NodeInfo>((resolve, reject) => {
|
|
17
|
+
const dom = uni.createSelectorQuery().in(context).select(selector);
|
|
18
|
+
const result: any = (rect: UniNamespace.NodeInfo) => {
|
|
19
|
+
if (rect) {
|
|
20
|
+
resolve(rect);
|
|
21
|
+
} else {
|
|
22
|
+
reject('no rect');
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
if (!node) {
|
|
27
|
+
dom.boundingClientRect(result).exec();
|
|
28
|
+
} else {
|
|
29
|
+
dom
|
|
30
|
+
.fields(
|
|
31
|
+
{
|
|
32
|
+
node: true,
|
|
33
|
+
size: true,
|
|
34
|
+
rect: true,
|
|
35
|
+
},
|
|
36
|
+
result,
|
|
37
|
+
)
|
|
38
|
+
.exec();
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export function addUnit(value?: string | number): string {
|
|
44
|
+
if (!value) {
|
|
45
|
+
return '0px';
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return typeof value === 'number' ? `${value}px` : value;
|
|
49
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<view class="capture-screen-content">
|
|
3
|
+
<view class="capture-screen-control">
|
|
4
|
+
<Tag style="margin-left: auto" mode="clear" @click="emit('clear')">
|
|
5
|
+
清空
|
|
6
|
+
</Tag>
|
|
7
|
+
</view>
|
|
8
|
+
|
|
9
|
+
<view class="capture-screen-list">
|
|
10
|
+
<view class="capture-screen-item" v-for="item in captureScreenList">
|
|
11
|
+
<view class="info-row">时间:{{ item.timer }} </view>
|
|
12
|
+
<view class="info-row">页面:{{ item.position }}</view>
|
|
13
|
+
</view>
|
|
14
|
+
|
|
15
|
+
<Empty v-if="!captureScreenList || captureScreenList.length === 0" />
|
|
16
|
+
</view>
|
|
17
|
+
</view>
|
|
18
|
+
</template>
|
|
19
|
+
<script lang="ts" setup>
|
|
20
|
+
import type { DevTool } from '../../type';
|
|
21
|
+
import Empty from '../Empty/index.vue';
|
|
22
|
+
import Tag from '../Tag/index.vue';
|
|
23
|
+
|
|
24
|
+
defineProps<{
|
|
25
|
+
captureScreenList: DevTool.CaptureScreenItem[];
|
|
26
|
+
}>();
|
|
27
|
+
|
|
28
|
+
const emit = defineEmits<{
|
|
29
|
+
(e: 'clear'): void;
|
|
30
|
+
}>();
|
|
31
|
+
</script>
|
|
32
|
+
<style scoped>
|
|
33
|
+
.capture-screen-content {
|
|
34
|
+
height: 100%;
|
|
35
|
+
font-size: var(--dev-tool-base-font-size);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
.capture-screen-list {
|
|
39
|
+
height: calc(100% - 32px);
|
|
40
|
+
overflow: auto;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.capture-screen-control {
|
|
44
|
+
display: flex;
|
|
45
|
+
align-items: center;
|
|
46
|
+
justify-content: space-between;
|
|
47
|
+
gap: 8px;
|
|
48
|
+
padding: 0 16px;
|
|
49
|
+
height: 32px;
|
|
50
|
+
border-bottom: 1px solid var(--dev-tool-border-color);
|
|
51
|
+
box-sizing: border-box;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.capture-screen-item {
|
|
55
|
+
padding: 16px;
|
|
56
|
+
border-bottom: 1px solid var(--dev-tool-border-color);
|
|
57
|
+
}
|
|
58
|
+
.info-row {
|
|
59
|
+
height: 28px;
|
|
60
|
+
line-height: 28px;
|
|
61
|
+
}
|
|
62
|
+
</style>
|
|
@@ -23,7 +23,9 @@
|
|
|
23
23
|
:key="index"
|
|
24
24
|
:class="`dev-tool-code-item ${index === activeRowCol.activeRow ? 'dev-tool-code-item-active' : ''}`"
|
|
25
25
|
>
|
|
26
|
-
<view class="dev-tool-code-item-index">
|
|
26
|
+
<view class="dev-tool-code-item-index">
|
|
27
|
+
{{ start + index + 1 }}
|
|
28
|
+
</view>
|
|
27
29
|
|
|
28
30
|
<view class="dev-tool-code-item-content" v-html="code"></view>
|
|
29
31
|
</view>
|
|
@@ -62,6 +64,10 @@ const codes = ref<string[]>([]);
|
|
|
62
64
|
|
|
63
65
|
const scrollIntoView = ref('');
|
|
64
66
|
|
|
67
|
+
const start = computed(() => {
|
|
68
|
+
return activeRowCol.value.row - 20 > 0 ? activeRowCol.value.row - 20 : 0;
|
|
69
|
+
});
|
|
70
|
+
|
|
65
71
|
function onClose() {
|
|
66
72
|
emit('close');
|
|
67
73
|
}
|
|
@@ -172,9 +178,6 @@ onMounted(() => {
|
|
|
172
178
|
top: 0;
|
|
173
179
|
left: 0;
|
|
174
180
|
padding: 0 16px;
|
|
175
|
-
/* #ifdef H5 */
|
|
176
|
-
padding: 50px 16px;
|
|
177
|
-
/* #endif */
|
|
178
181
|
|
|
179
182
|
background-color: rgba(255, 255, 255, 0.95);
|
|
180
183
|
box-sizing: border-box;
|