Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
qianlong66
uni-app
提交
b182de45
U
uni-app
项目概览
qianlong66
/
uni-app
与 Fork 源项目一致
Fork自
DCloud / uni-app
通知
1
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
U
uni-app
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
b182de45
编写于
7月 16, 2021
作者:
fxy060608
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
feat(app): add switchTab
上级
50dc7df0
变更
11
隐藏空白更改
内联
并排
Showing
11 changed file
with
277 addition
and
21 deletion
+277
-21
packages/shims-vue-runtime.d.ts
packages/shims-vue-runtime.d.ts
+1
-0
packages/uni-api/src/helpers/api/index.ts
packages/uni-api/src/helpers/api/index.ts
+6
-3
packages/uni-app-plus/dist/uni-app-service.es.js
packages/uni-app-plus/dist/uni-app-service.es.js
+114
-7
packages/uni-app-plus/src/service/api/index.ts
packages/uni-app-plus/src/service/api/index.ts
+1
-0
packages/uni-app-plus/src/service/api/route/reLaunch.ts
packages/uni-app-plus/src/service/api/route/reLaunch.ts
+4
-11
packages/uni-app-plus/src/service/api/route/switchTab.ts
packages/uni-app-plus/src/service/api/route/switchTab.ts
+134
-0
packages/uni-app-plus/src/service/api/route/utils.ts
packages/uni-app-plus/src/service/api/route/utils.ts
+12
-0
packages/uni-cli-shared/src/json/app/pages/uniConfig.ts
packages/uni-cli-shared/src/json/app/pages/uniConfig.ts
+2
-0
packages/uni-core/src/service/init/index.ts
packages/uni-core/src/service/init/index.ts
+1
-0
packages/uni-h5/dist/uni-h5.cjs.js
packages/uni-h5/dist/uni-h5.cjs.js
+1
-0
packages/uni-h5/dist/uni-h5.es.js
packages/uni-h5/dist/uni-h5.es.js
+1
-0
未找到文件。
packages/shims-vue-runtime.d.ts
浏览文件 @
b182de45
...
...
@@ -2,6 +2,7 @@ import { UniLifecycleHooks } from '@dcloudio/uni-vue/src/apiLifecycle'
import
{
ComponentCustomProperties
,
ComponentInternalInstance
}
from
'
vue
'
declare
module
'
@vue/runtime-core
'
{
interface
ComponentCustomProperties
{
route
:
string
$scope
:
{
$getAppWebview
?:
()
=>
PlusWebviewWebviewObject
}
...
...
packages/uni-api/src/helpers/api/index.ts
浏览文件 @
b182de45
...
...
@@ -131,11 +131,14 @@ function wrapperOffApi<T extends ApiLike>(
}
function
normalizeErrMsg
(
errMsg
:
string
|
Error
)
{
if
(
errMsg
instanceof
Error
)
{
console
.
error
(
errMsg
)
if
(
isString
(
errMsg
))
{
return
errMsg
}
if
(
errMsg
.
stack
)
{
console
.
error
(
errMsg
.
message
+
'
\n
'
+
errMsg
.
stack
)
return
errMsg
.
message
}
return
errMsg
return
errMsg
as
unknown
as
string
}
function
wrapperTaskApi
<
T
extends
ApiLike
>
(
...
...
packages/uni-app-plus/dist/uni-app-service.es.js
浏览文件 @
b182de45
...
...
@@ -525,8 +525,11 @@ var serviceContext = (function (vue) {
};
}
function normalizeErrMsg(errMsg) {
if (errMsg instanceof Error) {
console.error(errMsg);
if (isString(errMsg)) {
return errMsg;
}
if (errMsg.stack) {
console.error(errMsg.message + '\n' + errMsg.stack);
return errMsg.message;
}
return errMsg;
...
...
@@ -1801,6 +1804,7 @@ var serviceContext = (function (vue) {
appVm.$mpType = 'app';
}
function initPageVm(pageVm, page) {
pageVm.route = page.route;
pageVm.$vm = pageVm;
pageVm.$page = page;
pageVm.$mpType = 'page';
...
...
@@ -4420,12 +4424,15 @@ var serviceContext = (function (vue) {
}, createAnimationProtocol(ANIMATION_OUT));
const RedirectToProtocol = BaseRouteProtocol;
const ReLaunchProtocol = BaseRouteProtocol;
const SwitchTabProtocol = BaseRouteProtocol;
const NavigateToOptions =
/*#__PURE__*/ createRouteOptions(API_NAVIGATE_TO);
const RedirectToOptions =
/*#__PURE__*/ createRouteOptions(API_REDIRECT_TO);
const ReLaunchOptions =
/*#__PURE__*/ createRouteOptions(API_RE_LAUNCH);
const SwitchTabOptions =
/*#__PURE__*/ createRouteOptions(API_SWITCH_TAB);
const NavigateBackOptions = {
formatArgs: {
delta(value, params) {
...
...
@@ -9068,6 +9075,10 @@ var serviceContext = (function (vue) {
console.log(formatLog('setPendingNavigator', path, msg));
}
}
function closePage(page, animationType, animationDuration) {
removePage(page);
closeWebview(page.$getAppWebview(), animationType, animationDuration);
}
function navigate(path, callback, isAppLaunch = false) {
if (!isAppLaunch && pendingNavigator) {
return console.error(`Waiting to navigate to: ${pendingNavigator.path}, do not operate continuously: ${path}.`);
...
...
@@ -9757,16 +9768,111 @@ var serviceContext = (function (vue) {
query,
openType: 'reLaunch',
}), 'none', 0, () => {
pages.forEach((page) => {
removePage(page);
closeWebview(page.$getAppWebview(), 'none');
});
pages.forEach((page) => closePage(page, 'none'));
resolve(undefined);
});
setStatusBarStyle();
});
}
const switchTab = defineAsyncApi(API_SWITCH_TAB, (args, { resolve, reject }) => {
const { url } = args;
const { path, query } = parseUrl(url);
navigate(path, () => {
_switchTab({
url,
path,
query,
})
.then(resolve)
.catch(reject);
}, args.openType === 'appLaunch');
}, SwitchTabProtocol, SwitchTabOptions);
function _switchTab({ url, path, query, }) {
tabBar$1.switchTab(path.slice(1));
const pages = getCurrentPages();
const len = pages.length;
let callOnHide = false;
let callOnShow = false;
let currentPage;
if (len >= 1) {
// 前一个页面是非 tabBar 页面
currentPage = pages[len - 1];
if (currentPage && !currentPage.__isTabBar) {
// 前一个页面为非 tabBar 页面时,目标tabBar需要强制触发onShow
// 该情况下目标页tabBarPage的visible是不对的
// 除非每次路由跳转都处理一遍tabBarPage的visible,目前仅switchTab会处理
// 简单起见,暂时直接判断该情况,执行onShow
callOnShow = true;
pages.reverse().forEach((page) => {
if (!page.__isTabBar && page !== currentPage) {
closePage(page, 'none');
}
});
removePage(currentPage);
// 延迟执行避免iOS应用退出
setTimeout(() => {
if (currentPage.$page.openType === 'redirectTo') {
closeWebview(currentPage.$getAppWebview(), ANI_CLOSE, ANI_DURATION);
}
else {
closeWebview(currentPage.$getAppWebview(), 'auto');
}
}, 100);
}
else {
callOnHide = true;
}
}
let tabBarPage;
// 查找当前 tabBarPage,且设置 visible
getAllPages().forEach((page) => {
if ('/' + page.route === path) {
if (!page.$.__isActive) {
// 之前未显示
callOnShow = true;
}
page.$.__isActive = true;
tabBarPage = page;
}
else {
if (page.__isTabBar) {
page.$.__isActive = false;
}
}
});
// 相同tabBar页面
if (currentPage === tabBarPage) {
callOnHide = false;
}
if (currentPage && callOnHide) {
invokeHook(currentPage, 'onHide');
}
return new Promise((resolve) => {
if (tabBarPage) {
const webview = tabBarPage.$getAppWebview();
webview.show('none');
// 等visible状态都切换完之后,再触发onShow,否则开发者在onShow里边 getCurrentPages 会不准确
if (callOnShow && !webview.__preload__) {
invokeHook(tabBarPage, 'onShow');
}
resolve(undefined);
}
else {
showWebview(registerPage({
url,
path,
query,
openType: 'switchTab',
}), 'none', 0, () => {
setStatusBarStyle();
resolve(undefined);
}, 70);
}
setStatusBarStyle();
});
}
var uni$1 = /*#__PURE__*/Object.freeze({
__proto__: null,
upx2px: upx2px,
...
...
@@ -9897,7 +10003,8 @@ var serviceContext = (function (vue) {
navigateBack: navigateBack,
navigateTo: navigateTo,
redirectTo: redirectTo,
reLaunch: reLaunch
reLaunch: reLaunch,
switchTab: switchTab
});
let invokeViewMethodId = 0;
...
...
packages/uni-app-plus/src/service/api/index.ts
浏览文件 @
b182de45
...
...
@@ -56,6 +56,7 @@ export * from './route/navigateBack'
export
*
from
'
./route/navigateTo
'
export
*
from
'
./route/redirectTo
'
export
*
from
'
./route/reLaunch
'
export
*
from
'
./route/switchTab
'
export
{
upx2px
,
...
...
packages/uni-app-plus/src/service/api/route/reLaunch.ts
浏览文件 @
b182de45
...
...
@@ -6,13 +6,12 @@ import {
ReLaunchProtocol
,
}
from
'
@dcloudio/uni-api
'
import
{
parseUrl
}
from
'
@dcloudio/uni-shared
'
import
{
ComponentPublicInstance
}
from
'
vue
'
import
tabBar
from
'
../../framework/app/tabBar
'
import
{
registerPage
}
from
'
../../framework/page
'
import
{
getAllPages
,
removePage
}
from
'
../../framework/page/getCurrentPages
'
import
{
getAllPages
}
from
'
../../framework/page/getCurrentPages
'
import
{
setStatusBarStyle
}
from
'
../../statusBar
'
import
{
navigate
,
RouteOptions
}
from
'
./utils
'
import
{
closeWebview
,
showWebview
}
from
'
./webview
'
import
{
closePage
,
navigate
,
RouteOptions
}
from
'
./utils
'
import
{
showWebview
}
from
'
./webview
'
export
const
reLaunch
=
defineAsyncApi
<
API_TYPE_RE_LAUNCH
>
(
API_RE_LAUNCH
,
...
...
@@ -53,13 +52,7 @@ function _reLaunch({ url, path, query }: ReLaunchOptions): Promise<undefined> {
'
none
'
,
0
,
()
=>
{
pages
.
forEach
((
page
)
=>
{
removePage
(
page
)
closeWebview
(
(
page
as
ComponentPublicInstance
).
$getAppWebview
!
(),
'
none
'
)
})
pages
.
forEach
((
page
)
=>
closePage
(
page
,
'
none
'
))
resolve
(
undefined
)
}
)
...
...
packages/uni-app-plus/src/service/api/route/switchTab.ts
0 → 100644
浏览文件 @
b182de45
import
{
API_SWITCH_TAB
,
API_TYPE_SWITCH_TAB
,
defineAsyncApi
,
SwitchTabOptions
,
SwitchTabProtocol
,
}
from
'
@dcloudio/uni-api
'
import
{
invokeHook
}
from
'
@dcloudio/uni-core
'
import
{
parseUrl
}
from
'
@dcloudio/uni-shared
'
import
{
ComponentPublicInstance
}
from
'
vue
'
import
{
ANI_CLOSE
,
ANI_DURATION
}
from
'
../../constants
'
import
tabBar
from
'
../../framework/app/tabBar
'
import
{
registerPage
}
from
'
../../framework/page
'
import
{
getAllPages
,
removePage
}
from
'
../../framework/page/getCurrentPages
'
import
{
setStatusBarStyle
}
from
'
../../statusBar
'
import
{
closePage
,
navigate
,
RouteOptions
}
from
'
./utils
'
import
{
closeWebview
,
showWebview
}
from
'
./webview
'
export
const
switchTab
=
defineAsyncApi
<
API_TYPE_SWITCH_TAB
>
(
API_SWITCH_TAB
,
(
args
,
{
resolve
,
reject
})
=>
{
const
{
url
}
=
args
const
{
path
,
query
}
=
parseUrl
(
url
)
navigate
(
path
,
()
=>
{
_switchTab
({
url
,
path
,
query
,
})
.
then
(
resolve
)
.
catch
(
reject
)
},
(
args
as
any
).
openType
===
'
appLaunch
'
)
},
SwitchTabProtocol
,
SwitchTabOptions
)
interface
SwitchTabOptions
extends
RouteOptions
{}
function
_switchTab
({
url
,
path
,
query
,
}:
SwitchTabOptions
):
Promise
<
undefined
>
{
tabBar
.
switchTab
(
path
.
slice
(
1
))
const
pages
=
getCurrentPages
()
as
ComponentPublicInstance
[]
const
len
=
pages
.
length
let
callOnHide
=
false
let
callOnShow
=
false
let
currentPage
:
ComponentPublicInstance
|
undefined
if
(
len
>=
1
)
{
// 前一个页面是非 tabBar 页面
currentPage
=
pages
[
len
-
1
]
!
as
ComponentPublicInstance
if
(
currentPage
&&
!
currentPage
.
__isTabBar
)
{
// 前一个页面为非 tabBar 页面时,目标tabBar需要强制触发onShow
// 该情况下目标页tabBarPage的visible是不对的
// 除非每次路由跳转都处理一遍tabBarPage的visible,目前仅switchTab会处理
// 简单起见,暂时直接判断该情况,执行onShow
callOnShow
=
true
pages
.
reverse
().
forEach
((
page
)
=>
{
if
(
!
page
.
__isTabBar
&&
page
!==
currentPage
)
{
closePage
(
page
,
'
none
'
)
}
})
removePage
(
currentPage
)
// 延迟执行避免iOS应用退出
setTimeout
(()
=>
{
if
(
currentPage
!
.
$page
.
openType
===
'
redirectTo
'
)
{
closeWebview
(
currentPage
!
.
$getAppWebview
!
(),
ANI_CLOSE
,
ANI_DURATION
)
}
else
{
closeWebview
(
currentPage
!
.
$getAppWebview
!
(),
'
auto
'
)
}
},
100
)
}
else
{
callOnHide
=
true
}
}
let
tabBarPage
:
ComponentPublicInstance
|
undefined
// 查找当前 tabBarPage,且设置 visible
getAllPages
().
forEach
((
page
)
=>
{
if
(
'
/
'
+
page
.
route
===
path
)
{
if
(
!
page
.
$
.
__isActive
)
{
// 之前未显示
callOnShow
=
true
}
page
.
$
.
__isActive
=
true
tabBarPage
=
page
}
else
{
if
(
page
.
__isTabBar
)
{
page
.
$
.
__isActive
=
false
}
}
})
// 相同tabBar页面
if
(
currentPage
===
tabBarPage
)
{
callOnHide
=
false
}
if
(
currentPage
&&
callOnHide
)
{
invokeHook
(
currentPage
,
'
onHide
'
)
}
return
new
Promise
((
resolve
)
=>
{
if
(
tabBarPage
)
{
const
webview
=
tabBarPage
!
.
$getAppWebview
!
()
webview
.
show
(
'
none
'
)
// 等visible状态都切换完之后,再触发onShow,否则开发者在onShow里边 getCurrentPages 会不准确
if
(
callOnShow
&&
!
(
webview
as
any
).
__preload__
)
{
invokeHook
(
tabBarPage
,
'
onShow
'
)
}
resolve
(
undefined
)
}
else
{
showWebview
(
registerPage
({
url
,
path
,
query
,
openType
:
'
switchTab
'
,
}),
'
none
'
,
0
,
()
=>
{
setStatusBarStyle
()
resolve
(
undefined
)
},
70
)
}
setStatusBarStyle
()
})
}
packages/uni-app-plus/src/service/api/route/utils.ts
浏览文件 @
b182de45
import
{
getRouteMeta
}
from
'
@dcloudio/uni-core
'
import
{
formatLog
}
from
'
@dcloudio/uni-shared
'
import
{
ComponentPublicInstance
}
from
'
vue
'
import
{
removePage
}
from
'
../../framework/page/getCurrentPages
'
import
{
createPreloadWebview
,
onWebviewReady
,
preloadWebview
,
}
from
'
../../framework/webview
'
import
{
closeWebview
}
from
'
./webview
'
export
interface
RouteOptions
{
url
:
string
...
...
@@ -30,6 +33,15 @@ function setPendingNavigator(path: string, callback: Function, msg: string) {
}
}
export
function
closePage
(
page
:
ComponentPublicInstance
,
animationType
:
string
,
animationDuration
?:
number
)
{
removePage
(
page
)
closeWebview
(
page
.
$getAppWebview
!
(),
animationType
,
animationDuration
)
}
export
function
navigate
(
path
:
string
,
callback
:
Function
,
...
...
packages/uni-cli-shared/src/json/app/pages/uniConfig.ts
浏览文件 @
b182de45
...
...
@@ -27,6 +27,7 @@ interface AppUniConfig {
uploadFile
:
number
downloadFile
:
number
}
tabBar
?:
UniApp
.
UniConfig
[
'
tabBar
'
]
}
export
function
normalizeAppUniConfig
(
...
...
@@ -54,6 +55,7 @@ export function normalizeAppUniConfig(
compilerVersion
:
process
.
env
.
UNI_COMPILER_VERSION
,
entryPagePath
:
pagesJson
.
pages
[
0
].
path
,
networkTimeout
:
normalizeNetworkTimeout
(
manifestJson
.
networkTimeout
),
tabBar
:
pagesJson
.
tabBar
,
}
// TODO 待支持分包
return
JSON
.
stringify
(
config
)
...
...
packages/uni-core/src/service/init/index.ts
浏览文件 @
b182de45
...
...
@@ -19,6 +19,7 @@ export function initPageVm(
pageVm
:
ComponentPublicInstance
,
page
:
Page
.
PageInstance
[
'
$page
'
]
)
{
pageVm
.
route
=
page
.
route
pageVm
.
$vm
=
pageVm
pageVm
.
$page
=
page
pageVm
.
$mpType
=
'
page
'
...
...
packages/uni-h5/dist/uni-h5.cjs.js
浏览文件 @
b182de45
...
...
@@ -608,6 +608,7 @@ function initAppVm(appVm2) {
appVm2
.
$mpType
=
"
app
"
;
}
function
initPageVm
(
pageVm
,
page
)
{
pageVm
.
route
=
page
.
route
;
pageVm
.
$vm
=
pageVm
;
pageVm
.
$page
=
page
;
pageVm
.
$mpType
=
"
page
"
;
...
...
packages/uni-h5/dist/uni-h5.es.js
浏览文件 @
b182de45
...
...
@@ -1378,6 +1378,7 @@ function initAppVm(appVm2) {
appVm2.$mpType = "app";
}
function initPageVm(pageVm, page) {
pageVm.route = page.route;
pageVm.$vm = pageVm;
pageVm.$page = page;
pageVm.$mpType = "page";
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录