uview-pro 0.6.14 → 0.6.16
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/changelog.md +32 -11
- package/components/u-action-sheet/u-action-sheet.vue +1 -0
- package/components/u-alert-tips/u-alert-tips.vue +1 -0
- package/components/u-avatar/u-avatar.vue +1 -0
- package/components/u-back-top/u-back-top.vue +1 -0
- package/components/u-calendar/u-calendar.vue +3 -0
- package/components/u-car-keyboard/u-car-keyboard.vue +1 -0
- package/components/u-cell-item/u-cell-item.vue +1 -0
- package/components/u-checkbox/u-checkbox.vue +1 -0
- package/components/u-city-select/u-city-select.vue +5 -0
- package/components/u-collapse-item/u-collapse-item.vue +1 -0
- package/components/u-column-notice/u-column-notice.vue +1 -0
- package/components/u-dropdown/u-dropdown.vue +1 -0
- package/components/u-dropdown-item/u-dropdown-item.vue +3 -0
- package/components/u-empty/u-empty.vue +1 -0
- package/components/u-fab/u-fab.vue +2 -0
- package/components/u-field/u-field.vue +1 -0
- package/components/u-form-item/u-form-item.vue +1 -0
- package/components/u-full-screen/u-full-screen.vue +1 -0
- package/components/u-image/u-image.vue +1 -0
- package/components/u-input/u-input.vue +1 -0
- package/components/u-keyboard/u-keyboard.vue +3 -0
- package/components/u-loading-popup/u-loading-popup.vue +1 -0
- package/components/u-loadmore/u-loadmore.vue +2 -0
- package/components/u-modal/u-modal.vue +2 -0
- package/components/u-navbar/u-navbar.vue +1 -0
- package/components/u-notice-bar/u-notice-bar.vue +2 -0
- package/components/u-number-box/u-number-box.vue +1 -0
- package/components/u-number-keyboard/u-number-keyboard.vue +1 -0
- package/components/u-pagination/u-pagination.vue +3 -0
- package/components/u-picker/u-picker.vue +1 -0
- package/components/u-popup/u-popup.vue +2 -0
- package/components/u-radio/u-radio.vue +1 -0
- package/components/u-rate/u-rate.vue +1 -0
- package/components/u-read-more/u-read-more.vue +1 -0
- package/components/u-row-notice/u-row-notice.vue +1 -0
- package/components/u-search/u-search.vue +297 -296
- package/components/u-section/u-section.vue +1 -0
- package/components/u-select/u-select.vue +1 -0
- package/components/u-step/u-step.vue +30 -2
- package/components/u-steps/u-steps.vue +14 -1
- package/components/u-switch/u-switch.vue +1 -0
- package/components/u-tabbar/u-tabbar.vue +3 -0
- package/components/u-tabs/u-tabs.vue +1 -0
- package/components/u-tabs-swiper/u-tabs-swiper.vue +1 -0
- package/components/u-tag/u-tag.vue +1 -0
- package/components/u-text/u-text.vue +2 -0
- package/components/u-textarea/u-textarea.vue +1 -0
- package/components/u-toast/u-toast.vue +3 -0
- package/components/u-upload/u-upload.vue +2 -0
- package/package.json +21 -2
- package/plugins/root/page.ts +77 -77
- package/plugins/root/root.ts +53 -53
- package/types/index.d.ts +15 -14
|
@@ -42,6 +42,14 @@
|
|
|
42
42
|
<view class="u-steps__item__line" :class="['u-steps__item__line--' + mode]" v-if="showLine">
|
|
43
43
|
<u-line :direction="direction" length="100%" :hair-line="false" :color="unActiveColor"></u-line>
|
|
44
44
|
</view>
|
|
45
|
+
<!-- 横排模式下补左半连接线:节点宽度不一致时避免与上一个节点之间连线断开 -->
|
|
46
|
+
<view
|
|
47
|
+
class="u-steps__item__line"
|
|
48
|
+
:class="['u-steps__item__line--left--' + mode]"
|
|
49
|
+
v-if="direction === 'row' && childIndex > 0"
|
|
50
|
+
>
|
|
51
|
+
<u-line :direction="direction" length="100%" :hair-line="false" :color="unActiveColor"></u-line>
|
|
52
|
+
</view>
|
|
45
53
|
</view>
|
|
46
54
|
</template>
|
|
47
55
|
<script lang="ts">
|
|
@@ -60,6 +68,8 @@ export default {
|
|
|
60
68
|
import { computed } from 'vue';
|
|
61
69
|
import { $u, useChildren } from '../..';
|
|
62
70
|
import { StepProps } from './types';
|
|
71
|
+
import uIcon from '../u-icon/u-icon.vue';
|
|
72
|
+
import uLine from '../u-line/u-line.vue';
|
|
63
73
|
|
|
64
74
|
const props = defineProps(StepProps);
|
|
65
75
|
|
|
@@ -154,6 +164,8 @@ $u-steps-item-dot-width: 20rpx;
|
|
|
154
164
|
flex-direction: column;
|
|
155
165
|
|
|
156
166
|
&--row {
|
|
167
|
+
// 步骤多时禁止收缩到内容宽度以下,超宽交给容器横向滚动,避免文字遮挡
|
|
168
|
+
flex: 1 0 auto;
|
|
157
169
|
align-items: center;
|
|
158
170
|
@include vue-flex;
|
|
159
171
|
flex-direction: column;
|
|
@@ -162,17 +174,31 @@ $u-steps-item-dot-width: 20rpx;
|
|
|
162
174
|
position: absolute;
|
|
163
175
|
z-index: 0;
|
|
164
176
|
|
|
177
|
+
// 右半线:自本节点圆心向右伸至自身右边缘,与下一节点的左半线无缝衔接
|
|
165
178
|
&--dot {
|
|
166
|
-
width: calc(
|
|
179
|
+
width: calc(50% - #{$u-steps-item-dot-width} / 2);
|
|
167
180
|
top: calc(#{$u-steps-item-dot-width} / 2);
|
|
168
181
|
left: calc(#{$u-steps-item-dot-width} / 2 + 50%);
|
|
169
182
|
}
|
|
170
183
|
|
|
184
|
+
// 左半线:自自身左边缘向左半圆心(不含圆心),补偿右半线在宽度不同时够不到下一节点圆心
|
|
185
|
+
&--left--dot {
|
|
186
|
+
width: calc(50% - #{$u-steps-item-dot-width} / 2);
|
|
187
|
+
top: calc(#{$u-steps-item-dot-width} / 2);
|
|
188
|
+
right: calc(#{$u-steps-item-dot-width} / 2 + 50%);
|
|
189
|
+
}
|
|
190
|
+
|
|
171
191
|
&--number {
|
|
172
|
-
width: calc(
|
|
192
|
+
width: calc(50% - #{$u-steps-item-number-width} / 2);
|
|
173
193
|
top: calc(#{$u-steps-item-number-width} / 2);
|
|
174
194
|
left: calc(#{$u-steps-item-number-width} / 2 + 50%);
|
|
175
195
|
}
|
|
196
|
+
|
|
197
|
+
&--left--number {
|
|
198
|
+
width: calc(50% - #{$u-steps-item-number-width} / 2);
|
|
199
|
+
top: calc(#{$u-steps-item-number-width} / 2);
|
|
200
|
+
right: calc(#{$u-steps-item-number-width} / 2 + 50%);
|
|
201
|
+
}
|
|
176
202
|
}
|
|
177
203
|
}
|
|
178
204
|
|
|
@@ -250,6 +276,8 @@ $u-steps-item-dot-width: 20rpx;
|
|
|
250
276
|
}
|
|
251
277
|
|
|
252
278
|
&__desc--row {
|
|
279
|
+
// 保持单行,超宽由容器横向滚动承载
|
|
280
|
+
white-space: nowrap;
|
|
253
281
|
color: $u-type-info;
|
|
254
282
|
font-size: 24rpx;
|
|
255
283
|
}
|
|
@@ -55,6 +55,7 @@ export default {
|
|
|
55
55
|
import { computed, getCurrentInstance } from 'vue';
|
|
56
56
|
import { StepsProps } from './types';
|
|
57
57
|
import { $u, useParent } from '../..';
|
|
58
|
+
import uStep from '../u-step/u-step.vue';
|
|
58
59
|
|
|
59
60
|
/**
|
|
60
61
|
* steps 步骤条
|
|
@@ -75,7 +76,19 @@ const props = defineProps(StepsProps);
|
|
|
75
76
|
|
|
76
77
|
const { children } = useParent('u-steps');
|
|
77
78
|
// 计算方向样式
|
|
78
|
-
const directionStyle = computed(() =>
|
|
79
|
+
const directionStyle = computed(() => {
|
|
80
|
+
const isRow = props.direction === 'row';
|
|
81
|
+
return {
|
|
82
|
+
flexDirection: props.direction as 'row' | 'column',
|
|
83
|
+
...(isRow
|
|
84
|
+
? {
|
|
85
|
+
// 内容总宽超出一行时横向滚动,避免右侧节点被截断
|
|
86
|
+
overflowX: 'auto',
|
|
87
|
+
flexWrap: 'nowrap'
|
|
88
|
+
}
|
|
89
|
+
: {})
|
|
90
|
+
};
|
|
91
|
+
});
|
|
79
92
|
|
|
80
93
|
defineExpose({
|
|
81
94
|
props,
|
|
@@ -35,6 +35,7 @@ import { computed, nextTick } from 'vue';
|
|
|
35
35
|
import { $u, useChildren } from '../..';
|
|
36
36
|
import { SwitchProps } from './types';
|
|
37
37
|
import type { SizeType } from '../../types/global';
|
|
38
|
+
import uLoading from '../u-loading/u-loading.vue';
|
|
38
39
|
|
|
39
40
|
/**
|
|
40
41
|
* switch 开关选择器
|
|
@@ -103,6 +103,9 @@ import { ref, computed, onMounted } from 'vue';
|
|
|
103
103
|
import { $u } from '../..';
|
|
104
104
|
import { TabbarProps } from './types';
|
|
105
105
|
import type { TabbarItem } from '../../types/global';
|
|
106
|
+
import uBadge from '../u-badge/u-badge.vue';
|
|
107
|
+
import uGap from '../u-gap/u-gap.vue';
|
|
108
|
+
import uIcon from '../u-icon/u-icon.vue';
|
|
106
109
|
|
|
107
110
|
/**
|
|
108
111
|
* u-tabbar 底部导航栏
|
|
@@ -44,6 +44,7 @@ import { ref, computed, watch, nextTick, onMounted, getCurrentInstance } from 'v
|
|
|
44
44
|
import colorGradient from '../../libs/function/colorGradient';
|
|
45
45
|
import { TabsSwiperProps } from './types';
|
|
46
46
|
import { $u } from '../..';
|
|
47
|
+
import uBadge from '../u-badge/u-badge.vue';
|
|
47
48
|
|
|
48
49
|
/**
|
|
49
50
|
* tabsSwiper 全屏选项卡
|
|
@@ -91,6 +91,7 @@ import { ref, computed, watch, nextTick } from 'vue';
|
|
|
91
91
|
import { TextareaProps } from './types';
|
|
92
92
|
import { $u, useChildren } from '../../';
|
|
93
93
|
import type { SizeType } from '../../types/global';
|
|
94
|
+
import uIcon from '../u-icon/u-icon.vue';
|
|
94
95
|
|
|
95
96
|
/**
|
|
96
97
|
* Textarea 文本域
|
|
@@ -245,6 +245,8 @@ import { ref, watch, computed } from 'vue';
|
|
|
245
245
|
import { $u, useLocale } from '../..';
|
|
246
246
|
import { UploadProps } from './types';
|
|
247
247
|
import type { UploadFileItem } from '../../types/global';
|
|
248
|
+
import uIcon from '../u-icon/u-icon.vue';
|
|
249
|
+
import uLineProgress from '../u-line-progress/u-line-progress.vue';
|
|
248
250
|
|
|
249
251
|
/**
|
|
250
252
|
* upload 文件上传
|
package/package.json
CHANGED
|
@@ -2,12 +2,31 @@
|
|
|
2
2
|
"id": "uview-pro",
|
|
3
3
|
"name": "uview-pro",
|
|
4
4
|
"displayName": "【支持鸿蒙】uView Pro|基于Vue3+TS的高质量UI组件库,支持多主题、暗黑模式、多语言",
|
|
5
|
-
"version": "0.6.
|
|
5
|
+
"version": "0.6.16",
|
|
6
6
|
"description": "uView Pro是基于Vue3+TS的多平台UI框架,提供80+高质量组件、便捷工具和常用模板,支持多主题、暗黑模式、多语言,支持H5/APP/鸿蒙/小程序多端开发。已在鸿蒙应用商店上架,欢迎体验!",
|
|
7
7
|
"main": "index.ts",
|
|
8
8
|
"module": "index.ts",
|
|
9
9
|
"browser": "index.ts",
|
|
10
|
-
"types": "index.ts",
|
|
10
|
+
"types": "index.d.ts",
|
|
11
|
+
"exports": {
|
|
12
|
+
".": {
|
|
13
|
+
"types": "./index.d.ts",
|
|
14
|
+
"import": "./index.ts",
|
|
15
|
+
"require": "./index.ts",
|
|
16
|
+
"default": "./index.ts"
|
|
17
|
+
},
|
|
18
|
+
"./plugins": {
|
|
19
|
+
"types": "./plugins/index.ts",
|
|
20
|
+
"import": "./plugins/index.mjs",
|
|
21
|
+
"require": "./plugins/index.cjs",
|
|
22
|
+
"default": "./plugins/index.mjs"
|
|
23
|
+
},
|
|
24
|
+
"./types": "./types/index.d.ts",
|
|
25
|
+
"./types/*": "./types/*.d.ts",
|
|
26
|
+
"./components/*": "./components/*",
|
|
27
|
+
"./libs/*": "./libs/*",
|
|
28
|
+
"./*": "./*"
|
|
29
|
+
},
|
|
11
30
|
"keywords": [
|
|
12
31
|
"uview-pro",
|
|
13
32
|
"vue3",
|
package/plugins/root/page.ts
CHANGED
|
@@ -1,77 +1,77 @@
|
|
|
1
|
-
import { parseSFC, findNode } from './utils';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* 页面模板转换:将页面内容包裹在 <global-root-view> 中
|
|
5
|
-
*
|
|
6
|
-
* <global-root-view> 是 App.root.vue 注册的全局组件,
|
|
7
|
-
* 其模板中包含 <slot />,页面内容通过插槽传入。
|
|
8
|
-
*
|
|
9
|
-
* 处理逻辑:
|
|
10
|
-
* 1. 解析 SFC,定位 <template> 标签的起止位置
|
|
11
|
-
* 2. 提取模板内容,查找 PageMeta 节点(如有则提取到包裹层外部)
|
|
12
|
-
* 3. 将剩余内容包裹在 <global-root-view>...</global-root-view> 中
|
|
13
|
-
*
|
|
14
|
-
* 降级机制:当 vue/compiler-sfc 不可用(如 HBuilderX 项目)时,
|
|
15
|
-
* 使用正则匹配 <page-meta> 标签替代 AST 解析。
|
|
16
|
-
*/
|
|
17
|
-
export async function transformPage(code: string) {
|
|
18
|
-
const sfc = await parseSFC(code);
|
|
19
|
-
|
|
20
|
-
// 用正则定位 <template> 开头标签
|
|
21
|
-
const openMatch = code.match(/<template\b[^>]*>/);
|
|
22
|
-
if (!openMatch) return null;
|
|
23
|
-
|
|
24
|
-
// 使用 lastIndexOf 定位最后一个 </template>,即根 <template> 的闭合标签
|
|
25
|
-
// 避免匹配到模板内具名插槽 <template #slot> 的闭合标签
|
|
26
|
-
const closeTagStart = code.lastIndexOf('</template>');
|
|
27
|
-
if (closeTagStart === -1) return null;
|
|
28
|
-
|
|
29
|
-
const openTagEnd = openMatch.index! + openMatch[0].length;
|
|
30
|
-
const content = code.slice(openTagEnd, closeTagStart);
|
|
31
|
-
|
|
32
|
-
let pageMetaSource = '';
|
|
33
|
-
let newContent = content;
|
|
34
|
-
|
|
35
|
-
if (sfc?.template) {
|
|
36
|
-
// AST 模式:通过 vue/compiler-sfc 解析,精确定位 PageMeta 节点
|
|
37
|
-
const pageMetaNode = findNode(sfc, 'PageMeta');
|
|
38
|
-
if (pageMetaNode) {
|
|
39
|
-
pageMetaSource = pageMetaNode.loc.source;
|
|
40
|
-
const metaStart = pageMetaNode.loc.start.offset;
|
|
41
|
-
const metaEnd = pageMetaNode.loc.end.offset;
|
|
42
|
-
|
|
43
|
-
// pageMetaNode.loc 的 offset 是相对于整个文件的,转换为相对于 content 的位置
|
|
44
|
-
const metaStartInContent = metaStart - openTagEnd;
|
|
45
|
-
const metaEndInContent = metaEnd - openTagEnd;
|
|
46
|
-
|
|
47
|
-
newContent = content.slice(0, metaStartInContent) + content.slice(metaEndInContent);
|
|
48
|
-
}
|
|
49
|
-
} else {
|
|
50
|
-
// 降级模式:vue/compiler-sfc 不可用,用正则匹配 <page-meta> 标签
|
|
51
|
-
const pageMetaMatch = content.match(/<page-meta\b[^>]*>[\s\S]*?<\/page-meta>/);
|
|
52
|
-
if (pageMetaMatch) {
|
|
53
|
-
pageMetaSource = pageMetaMatch[0];
|
|
54
|
-
newContent = content.replace(pageMetaMatch[0], '');
|
|
55
|
-
} else {
|
|
56
|
-
// 也匹配自闭合的 <page-meta ... />
|
|
57
|
-
const selfClosingMatch = content.match(/<page-meta\b[^>]*\/>/);
|
|
58
|
-
if (selfClosingMatch) {
|
|
59
|
-
pageMetaSource = selfClosingMatch[0];
|
|
60
|
-
newContent = content.replace(selfClosingMatch[0], '');
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
// page-meta 放在包裹层外部,内容包裹在 <global-root-view> 中
|
|
66
|
-
const wrappedContent = `\n${pageMetaSource}\n<global-root-view>${newContent}</global-root-view>\n`;
|
|
67
|
-
|
|
68
|
-
return {
|
|
69
|
-
code: code.slice(0, openTagEnd) + wrappedContent + code.slice(closeTagStart),
|
|
70
|
-
map: {
|
|
71
|
-
version: 3 as const,
|
|
72
|
-
sources: [] as string[],
|
|
73
|
-
names: [] as string[],
|
|
74
|
-
mappings: ''
|
|
75
|
-
}
|
|
76
|
-
};
|
|
77
|
-
}
|
|
1
|
+
import { parseSFC, findNode } from './utils';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* 页面模板转换:将页面内容包裹在 <global-root-view> 中
|
|
5
|
+
*
|
|
6
|
+
* <global-root-view> 是 App.root.vue 注册的全局组件,
|
|
7
|
+
* 其模板中包含 <slot />,页面内容通过插槽传入。
|
|
8
|
+
*
|
|
9
|
+
* 处理逻辑:
|
|
10
|
+
* 1. 解析 SFC,定位 <template> 标签的起止位置
|
|
11
|
+
* 2. 提取模板内容,查找 PageMeta 节点(如有则提取到包裹层外部)
|
|
12
|
+
* 3. 将剩余内容包裹在 <global-root-view>...</global-root-view> 中
|
|
13
|
+
*
|
|
14
|
+
* 降级机制:当 vue/compiler-sfc 不可用(如 HBuilderX 项目)时,
|
|
15
|
+
* 使用正则匹配 <page-meta> 标签替代 AST 解析。
|
|
16
|
+
*/
|
|
17
|
+
export async function transformPage(code: string) {
|
|
18
|
+
const sfc = await parseSFC(code);
|
|
19
|
+
|
|
20
|
+
// 用正则定位 <template> 开头标签
|
|
21
|
+
const openMatch = code.match(/<template\b[^>]*>/);
|
|
22
|
+
if (!openMatch) return null;
|
|
23
|
+
|
|
24
|
+
// 使用 lastIndexOf 定位最后一个 </template>,即根 <template> 的闭合标签
|
|
25
|
+
// 避免匹配到模板内具名插槽 <template #slot> 的闭合标签
|
|
26
|
+
const closeTagStart = code.lastIndexOf('</template>');
|
|
27
|
+
if (closeTagStart === -1) return null;
|
|
28
|
+
|
|
29
|
+
const openTagEnd = openMatch.index! + openMatch[0].length;
|
|
30
|
+
const content = code.slice(openTagEnd, closeTagStart);
|
|
31
|
+
|
|
32
|
+
let pageMetaSource = '';
|
|
33
|
+
let newContent = content;
|
|
34
|
+
|
|
35
|
+
if (sfc?.template) {
|
|
36
|
+
// AST 模式:通过 vue/compiler-sfc 解析,精确定位 PageMeta 节点
|
|
37
|
+
const pageMetaNode = findNode(sfc, 'PageMeta');
|
|
38
|
+
if (pageMetaNode) {
|
|
39
|
+
pageMetaSource = pageMetaNode.loc.source;
|
|
40
|
+
const metaStart = pageMetaNode.loc.start.offset;
|
|
41
|
+
const metaEnd = pageMetaNode.loc.end.offset;
|
|
42
|
+
|
|
43
|
+
// pageMetaNode.loc 的 offset 是相对于整个文件的,转换为相对于 content 的位置
|
|
44
|
+
const metaStartInContent = metaStart - openTagEnd;
|
|
45
|
+
const metaEndInContent = metaEnd - openTagEnd;
|
|
46
|
+
|
|
47
|
+
newContent = content.slice(0, metaStartInContent) + content.slice(metaEndInContent);
|
|
48
|
+
}
|
|
49
|
+
} else {
|
|
50
|
+
// 降级模式:vue/compiler-sfc 不可用,用正则匹配 <page-meta> 标签
|
|
51
|
+
const pageMetaMatch = content.match(/<page-meta\b[^>]*>[\s\S]*?<\/page-meta>/);
|
|
52
|
+
if (pageMetaMatch) {
|
|
53
|
+
pageMetaSource = pageMetaMatch[0];
|
|
54
|
+
newContent = content.replace(pageMetaMatch[0], '');
|
|
55
|
+
} else {
|
|
56
|
+
// 也匹配自闭合的 <page-meta ... />
|
|
57
|
+
const selfClosingMatch = content.match(/<page-meta\b[^>]*\/>/);
|
|
58
|
+
if (selfClosingMatch) {
|
|
59
|
+
pageMetaSource = selfClosingMatch[0];
|
|
60
|
+
newContent = content.replace(selfClosingMatch[0], '');
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// page-meta 放在包裹层外部,内容包裹在 <global-root-view> 中
|
|
66
|
+
const wrappedContent = `\n${pageMetaSource}\n<global-root-view>${newContent}</global-root-view>\n`;
|
|
67
|
+
|
|
68
|
+
return {
|
|
69
|
+
code: code.slice(0, openTagEnd) + wrappedContent + code.slice(closeTagStart),
|
|
70
|
+
map: {
|
|
71
|
+
version: 3 as const,
|
|
72
|
+
sources: [] as string[],
|
|
73
|
+
names: [] as string[],
|
|
74
|
+
mappings: ''
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
}
|
package/plugins/root/root.ts
CHANGED
|
@@ -1,53 +1,53 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 创建一个最小的 sourcemap,用于满足 Vite/Rollup 的 sourcemap 要求。
|
|
3
|
-
*
|
|
4
|
-
* 这是一个空映射的 sourcemap(mappings 为空字符串),不提供精确的源码映射,
|
|
5
|
-
* 但可以避免 "Sourcemap is likely to be incorrect" 警告。
|
|
6
|
-
* 调试器会回退到显示转换后的代码,不影响功能。
|
|
7
|
-
*
|
|
8
|
-
* 纯 JS 实现,无需第三方依赖。
|
|
9
|
-
*/
|
|
10
|
-
function createEmptySourcemap() {
|
|
11
|
-
return {
|
|
12
|
-
version: 3 as const,
|
|
13
|
-
sources: [] as string[],
|
|
14
|
-
names: [] as string[],
|
|
15
|
-
mappings: ''
|
|
16
|
-
};
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* 向 main.ts 注入 App.root.vue 的导入和全局注册
|
|
21
|
-
*
|
|
22
|
-
* 流程:
|
|
23
|
-
* 1. 在文件顶部插入 `import GlobalRootView from "./App.root.vue"`
|
|
24
|
-
* 2. 在 createSSRApp 之后插入 `app.component("global-root-view", GlobalRootView)`
|
|
25
|
-
*
|
|
26
|
-
* 注:GlobalRootView 仅为 main.ts 中的局部变量名,
|
|
27
|
-
* 实际组件就是 App.root.vue,页面通过 <global-root-view> 标签使用。
|
|
28
|
-
*/
|
|
29
|
-
export function registerRootApp(code: string, fileName: string = 'App.root') {
|
|
30
|
-
const importCode = `import GlobalRootView from "./${fileName}.vue";`;
|
|
31
|
-
const vueUseComponentCode = `app.component("global-root-view", GlobalRootView);`;
|
|
32
|
-
|
|
33
|
-
let newCode = importCode + '\n' + code;
|
|
34
|
-
|
|
35
|
-
// 在 createSSRApp 赋值语句之后插入组件注册代码
|
|
36
|
-
const ssrAppMatch = newCode.match(/(const\s+app\s*=\s*createSSRApp\([^)]+\);)/);
|
|
37
|
-
if (ssrAppMatch) {
|
|
38
|
-
newCode = newCode.replace(/(const\s+app\s*=\s*createSSRApp\([^)]+\);)/, `$1\n ${vueUseComponentCode}`);
|
|
39
|
-
} else {
|
|
40
|
-
// 兜底:在 return { 之前插入
|
|
41
|
-
newCode = newCode.replace(/(createApp[\s\S]*?)(return\s*\{)/, `$1${vueUseComponentCode}\n $2`);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
return { code: newCode, map: createEmptySourcemap() };
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* App.root.vue 模板中已使用 <slot /> 作为子内容插槽,
|
|
49
|
-
* 无需替换,直接透传。
|
|
50
|
-
*/
|
|
51
|
-
export function rebuildRootApp(code: string) {
|
|
52
|
-
return { code, map: createEmptySourcemap() };
|
|
53
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* 创建一个最小的 sourcemap,用于满足 Vite/Rollup 的 sourcemap 要求。
|
|
3
|
+
*
|
|
4
|
+
* 这是一个空映射的 sourcemap(mappings 为空字符串),不提供精确的源码映射,
|
|
5
|
+
* 但可以避免 "Sourcemap is likely to be incorrect" 警告。
|
|
6
|
+
* 调试器会回退到显示转换后的代码,不影响功能。
|
|
7
|
+
*
|
|
8
|
+
* 纯 JS 实现,无需第三方依赖。
|
|
9
|
+
*/
|
|
10
|
+
function createEmptySourcemap() {
|
|
11
|
+
return {
|
|
12
|
+
version: 3 as const,
|
|
13
|
+
sources: [] as string[],
|
|
14
|
+
names: [] as string[],
|
|
15
|
+
mappings: ''
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* 向 main.ts 注入 App.root.vue 的导入和全局注册
|
|
21
|
+
*
|
|
22
|
+
* 流程:
|
|
23
|
+
* 1. 在文件顶部插入 `import GlobalRootView from "./App.root.vue"`
|
|
24
|
+
* 2. 在 createSSRApp 之后插入 `app.component("global-root-view", GlobalRootView)`
|
|
25
|
+
*
|
|
26
|
+
* 注:GlobalRootView 仅为 main.ts 中的局部变量名,
|
|
27
|
+
* 实际组件就是 App.root.vue,页面通过 <global-root-view> 标签使用。
|
|
28
|
+
*/
|
|
29
|
+
export function registerRootApp(code: string, fileName: string = 'App.root') {
|
|
30
|
+
const importCode = `import GlobalRootView from "./${fileName}.vue";`;
|
|
31
|
+
const vueUseComponentCode = `app.component("global-root-view", GlobalRootView);`;
|
|
32
|
+
|
|
33
|
+
let newCode = importCode + '\n' + code;
|
|
34
|
+
|
|
35
|
+
// 在 createSSRApp 赋值语句之后插入组件注册代码
|
|
36
|
+
const ssrAppMatch = newCode.match(/(const\s+app\s*=\s*createSSRApp\([^)]+\);)/);
|
|
37
|
+
if (ssrAppMatch) {
|
|
38
|
+
newCode = newCode.replace(/(const\s+app\s*=\s*createSSRApp\([^)]+\);)/, `$1\n ${vueUseComponentCode}`);
|
|
39
|
+
} else {
|
|
40
|
+
// 兜底:在 return { 之前插入
|
|
41
|
+
newCode = newCode.replace(/(createApp[\s\S]*?)(return\s*\{)/, `$1${vueUseComponentCode}\n $2`);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return { code: newCode, map: createEmptySourcemap() };
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* App.root.vue 模板中已使用 <slot /> 作为子内容插槽,
|
|
49
|
+
* 无需替换,直接透传。
|
|
50
|
+
*/
|
|
51
|
+
export function rebuildRootApp(code: string) {
|
|
52
|
+
return { code, map: createEmptySourcemap() };
|
|
53
|
+
}
|
package/types/index.d.ts
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
|
-
/// <reference path="./components.d.ts" />
|
|
2
|
-
/// <reference path="./uni-app.d.ts" />
|
|
3
|
-
|
|
4
|
-
export * from './global';
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
1
|
+
/// <reference path="./components.d.ts" />
|
|
2
|
+
/// <reference path="./uni-app.d.ts" />
|
|
3
|
+
|
|
4
|
+
export * from './global';
|
|
5
|
+
export * from '../libs';
|
|
6
|
+
|
|
7
|
+
declare global {
|
|
8
|
+
interface Uni {
|
|
9
|
+
$u: typeof import('../libs').$u;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
declare module 'uview-pro' {
|
|
14
|
+
export function install(app: any, options?: import('./global').UViewProOptions): void;
|
|
15
|
+
}
|