React 导航
本指南介绍了路由如何在使用 Ionic 和 React 构建的应用中工作。
¥This guide covers how routing works in an app built with Ionic and React.
IonReactRouter
在底层使用了流行的 反应路由 库。使用 Ionic 和 React Router,你可以创建具有丰富页面转换的多页面应用。
¥IonReactRouter
uses the popular React Router library under the hood. With Ionic and React Router, you can create multi-page apps with rich page transitions.
你所了解的有关使用 React Router 进行路由的所有知识都会延续到 Ionic React 中。让我们看一下 Ionic React 应用的基础知识以及路由如何与其配合使用。
¥Everything you know about routing using React Router carries over into Ionic React. Let's take a look at the basics of an Ionic React app and how routing works with it.
Ionic React 中的路由
¥Routing in Ionic React
下面是一个示例 App
组件,它定义了到 "/dashboard" URL 的单个路由。当你访问 "/dashboard" 时,路由会渲染 DashboardPage
组件。
¥Here is a sample App
component that defines a single route to the "/dashboard" URL. When you visit "/dashboard", the route renders the DashboardPage
component.
App.tsx
const App: React.FC = () => (
<IonApp>
<IonReactRouter>
<IonRouterOutlet>
<Route path="/dashboard" component={DashboardPage} />
<Redirect exact from="/" to="/dashboard" />
</IonRouterOutlet>
</IonReactRouter>
</IonApp>
);
紧接着 Route
,我们定义了默认的 Redirect
,当用户访问应用的根 URL ("/") 时,它会将其重定向到 "/dashboard" URL。
¥Directly after the Route
, we define our default Redirect
, which, when a user visits the root URL of the app ("/"), it redirects them to the "/dashboard" URL.
重定向还设置了 exact
属性,这意味着 URL 必须精确匹配 from
属性(如果在 Route
上使用 exact
,则为 path
属性),此路由才能匹配。如果没有它,此重定向将为每个路由渲染,因为每个路由都以 "/" 开头。
¥The redirect also has the exact
prop set, which means the URL has to match the from
prop (or the path
prop if exact
was used on a Route
) precisely for this route to be a match. Without it, this redirect would render for every route, since every route begins with "/".
你还可以根据条件以编程方式从路由的渲染方法进行重定向,例如检查用户是否经过身份验证:
¥You can also programmatically redirect from a Route's render method based on a condition, like checking if a user is authed or not:
<Route
exact
path="/dashboard"
render={(props) => {
return isAuthed ? <DashboardPage {...props} /> : <LoginPage />;
}}
/>
IonReactRouter
IonReactRouter
组件封装了 React Router 中的传统 BrowserRouter
组件,并设置应用进行路由。因此,使用 IonReactRouter
代替 BrowserRouter
。你可以将任何 props 传递给 IonReactRouter
,它们将被传递给底层的 BrowserRouter
。
¥The IonReactRouter
component wraps the traditional BrowserRouter
component from React Router, and sets the app up for routing. Therefore, use IonReactRouter
in place of BrowserRouter
. You can pass in any props to IonReactRouter
and they will be passed down to the underlying BrowserRouter
.
嵌套路由
¥Nested Routes
在仪表板页面内,我们定义了与应用的此特定部分相关的更多路由:
¥Inside the Dashboard page, we define more routes related to this specific section of the app:
DashboardPage.tsx
const DashboardPage: React.FC = () => {
return (
<IonPage>
<IonRouterOutlet>
<Route exact path="/dashboard" component={UsersListPage} />
<Route path="/dashboard/users/:id" component={UserDetailPage} />
</IonRouterOutlet>
</IonPage>
);
};
在这里,定义了更多路由来指向应用仪表板部分内的页面。请注意,我们需要在路径中定义整个路由,即使我们从该 URL 到达此页面,我们也不能省略 "/dashboard"。React Router 需要完整路径,不支持相对路径。
¥Here, there are a couple more routes defined to point to pages from within the dashboard portion of the app. Note, that we need to define the whole route in the path, and we can't leave off "/dashboard" even though we arrived to this page from that URL. React Router requires full paths, and relative paths are not supported.
但是,我们可以使用 match
对象 url
属性来提供与渲染组件相匹配的 URL,这在使用嵌套路由时会有所帮助:
¥However, we can use the match
objects url
property to provide the URL that was matched to render a component, which helps when working with nested routes:
const DashboardPage: React.FC<RouteComponentProps> = ({ match }) => {
return (
<IonPage>
<IonRouterOutlet>
<Route exact path={match.url} component={UsersListPage} />
<Route path={`${match.url}/users/:id`} component={UserDetailPage} />
</IonRouterOutlet>
</IonPage>
);
};
这里,match.url
包含 "/dashboard" 的值,因为那是用于渲染 DashboardPage
的 URL。
¥Here, match.url
contains the value of "/dashboard", since that was the URL used to render the DashboardPage
.
这些路由被分组在 IonRouterOutlet
中,我们接下来讨论一下。
¥These routes are grouped in an IonRouterOutlet
, let's discuss that next.
IonRouterOutlet
IonRouterOutlet
组件为渲染 Ionic "pages" 的路由提供了一个容器。当页面处于 IonRouterOutlet
时,容器控制页面之间的过渡动画以及页面创建和销毁的时间,这有助于在视图之间来回切换时维护视图之间的状态。
¥The IonRouterOutlet
component provides a container for Routes that render Ionic "pages". When a page is in an IonRouterOutlet
, the container controls the transition animation between the pages as well as controls when a page is created and destroyed, which helps maintain the state between the views when switching back and forth between them.
上面的 DashboardPage
显示了用户列表页面和详细信息页面。在两个页面之间导航时,IonRouterOutlet
提供适当的平台页面转换并保持前一页的状态不变,以便当用户导航回列表页面时,它会显示与离开时相同的状态。
¥The DashboardPage
above shows a users list page and a details page. When navigating between the two pages, the IonRouterOutlet
provides the appropriate platform page transition and keeps the state of the previous page intact so that when a user navigates back to the list page, it appears in the same state as when it left.
IonRouterOutlet
只能包含 Route
或 Redirect
。任何其他组件都应作为 Route
的结果或在 IonRouterOutlet
之外渲染。
¥An IonRouterOutlet
should only contain Route
s or Redirect
s. Any other component should be rendered either as a result of a Route
or outside of the IonRouterOutlet
.
后备路由
¥Fallback Route
常见的路由用例是在导航到的位置与定义的任何路由都不匹配的情况下提供要渲染的 "fallback" 路由。
¥A common routing use case is to provide a "fallback" route to be rendered in the event the location navigated to does not match any of the routes defined.
我们可以通过将没有 path
属性的 Route
组件放置为 IonRouterOutlet
中定义的最后一个路由来定义后备路由。
¥We can define a fallback route by placing a Route
component without a path
property as the last route defined within an IonRouterOutlet
.
DashboardPage.tsx
const DashboardPage: React.FC<RouteComponentProps> = ({ match }) => {
return (
<IonRouterOutlet>
<Route exact path={match.url} component={UsersListPage} />
<Route path={`${match.url}/users/:id`} component={UserDetailPage} />
<Route render={() => <Redirect to={match.url} />} />
</IonRouterOutlet>
);
};
在这里,我们看到,如果位置与前两个 Route
不匹配,IonRouterOutlet
会将 Ionic React 应用重定向到 match.url
路径。
¥Here, we see that in the event a location does not match the first two Route
s the IonRouterOutlet
will redirect the Ionic React app to the match.url
path.
你也可以提供一个组件来渲染,而不是提供重定向。
¥You can alternatively supply a component to render instead of providing a redirect.
const DashboardPage: React.FC<RouteComponentProps> = ({ match }) => {
return (
<IonRouterOutlet>
<Route exact path={match.url} component={UsersListPage} />
<Route path={`${match.url}/users/:id`} component={UserDetailPage} />
<Route component={NotFoundPage} />
</IonRouterOutlet>
);
};
IonPage
IonPage
组件将每个视图封装在 Ionic React 应用中,并允许页面转换和堆栈导航正常工作。使用路由导航到的每个视图都必须包含 IonPage
组件。
¥The IonPage
component wraps each view in an Ionic React app and allows page transitions and stack navigation to work properly. Each view that is navigated to using the router must include an IonPage
component.
import { IonContent, IonHeader, IonPage, IonTitle, IonToolbar } from '@ionic/react';
import React from 'react';
const Home: React.FC = () => {
return (
<IonPage>
<IonHeader>
<IonToolbar>
<IonTitle>Home</IonTitle>
</IonToolbar>
</IonHeader>
<IonContent className="ion-padding">Hello World</IonContent>
</IonPage>
);
};
export default Home;
导航
¥Navigation
在 Ionic React 应用中路由到不同视图时,有多个选项可用。在这里,UsersListPage
使用 IonItem
的 routerLink
属性来指定点击/单击项目时要转到的路由:
¥There are several options available when routing to different views in an Ionic React app. Here, the UsersListPage
uses IonItem
's routerLink
prop to specify the route to go to when the item is tapped/clicked:
UsersListPage.tsx
const UsersListPage: React.FC = () => {
return (
<IonPage>
<IonHeader>
<IonToolbar>
<IonTitle>Users</IonTitle>
</IonToolbar>
</IonHeader>
<IonContent>
<IonList>
<IonItem routerLink="/dashboard/users/1">
<IonLabel>User 1</IonLabel>
</IonItem>
<IonItem routerLink="/dashboard/users/2">
<IonLabel>User 2</IonLabel>
</IonItem>
</IonList>
</IonContent>
</IonPage>
);
};
其他具有 routerLink
属性的组件有 IonButton
、IonCard
、IonRouterLink
、IonFabButton
和 IonItemOption
。
¥Other components that have the routerLink
prop are IonButton
, IonCard
, IonRouterLink
, IonFabButton
, and IonItemOption
.
每个组件还有一个 routerDirection
属性来显式设置要使用的页面转换类型("back"、"forward" 或 "none")。
¥Each of these components also have a routerDirection
prop to explicitly set the type of page transition to use ("back", "forward", or "none").
除了这些具有 routerLink
属性的组件之外,你还可以使用 React Routers Link
组件在视图之间导航:
¥Outside of these components that have the routerLink
prop, you can also use React Routers Link
component to navigate between views:
<Link to="/dashboard/users/1">User 1</Link>
我们建议尽可能使用上述方法之一进行路由。这些方法的优点是它们都渲染锚点 (<a>
) 标签,适合整体应用可访问性。
¥We recommend using one of the above methods whenever possible for routing. The advantage to these approaches is that they both render an anchor (<a>
)tag, which is suitable for overall app accessibility.
导航的编程选项是使用 React Router 向其通过路由渲染的组件提供的 history
属性。
¥A programmatic option for navigation is using the history
prop that React Router provides to the components it renders via routes.
<IonButton
onClick={(e) => {
e.preventDefault();
history.push('/dashboard/users/1');
}}
>
Go to User 1
</IonButton>
history
是一个属性。
¥history
is a prop.
使用 history.go
导航
¥Navigating using history.go
React Router 使用 history
包,该包具有 history.go 方法,允许开发者在应用历史记录中向前或向后移动。让我们看一个例子。
¥React Router uses the history
package which has a history.go method that allows developers to move forward or backward through the application history. Let's take a look at an example.
假设你有以下应用历史记录:
¥Say you have the following application history:
/pageA
--> /pageB
--> /pageC
如果你在 /pageC
上调用 router.go(-2)
,你将被带回到 /pageA
。如果你随后调用 router.go(2)
,你将被带到 /pageC
。
¥If you were to call router.go(-2)
on /pageC
, you would be brought back to /pageA
. If you then called router.go(2)
, you would be brought to /pageC
.
目前不支持在 Ionic React 中使用 history.go()
。有兴趣看到 Ionic React 中添加对此的支持吗?在 GitHub 上告诉我们!
¥Using history.go()
in Ionic React is not supported at the moment. Interested in seeing support for this get added to Ionic React? Let us know on GitHub!
网址参数
¥URL Parameters
仪表板页面中定义的第二条路由定义了 URL 参数(路径中的 ":ID" 部分)。URL 参数是 path
的动态部分,当用户导航到 "/dashboard/users/1" 这样的 URL 时,"1" 会保存到名为 "id" 的参数中,可以在路由渲染的组件中访问该参数。让我们看看这是如何做到的。
¥The second route defined in the Dashboard Page has a URL parameter defined (the ":id" portion in the path). URL parameters are dynamic portions of the path
, and when the user navigates to a URL such as "/dashboard/users/1", the "1" is saved to a parameter named "id", which can be accessed in the component the route renders. Let's see how that's done.
UserDetailPage.tsx
interface UserDetailPageProps
extends RouteComponentProps<{
id: string;
}> {}
const UserDetailPage: React.FC<UserDetailPageProps> = ({ match }) => {
return (
<IonPage>
<IonHeader>
<IonToolbar>
<IonTitle>User Detail</IonTitle>
</IonToolbar>
</IonHeader>
<IonContent>User {match.params.id}</IonContent>
</IonPage>
);
};
match
属性包含有关匹配路由的信息,包括 URL 参数。我们在这里获取 id
参数并将其显示在屏幕上。
¥The match
prop contains information about the matched route, including the URL params. We obtain the id
param here and display it on the screen.
请注意我们如何使用 TypeScript 接口来强类型化 props 对象。该接口为我们提供了组件内部的类型安全和代码完成。
¥Note how we use a TypeScript interface to strongly type the props object. The interface gives us type safety and code completion inside of the component.
线性路由与非线性路由
¥Linear Routing versus Non-Linear Routing
线性路由
¥Linear Routing
如果你构建了一个使用路由的 Web 应用,那么你以前可能使用过线性路由。线性路由意味着你可以通过推送和弹出页面在应用历史记录中向前或向后移动。
¥If you have built a web app that uses routing, you likely have used linear routing before. Linear routing means that you can move forward or backward through the application history by pushing and popping pages.
以下是移动应用中线性路由的示例:
¥The following is an example of linear routing in a mobile app:
本例中的应用历史记录具有以下路径:
¥The application history in this example has the following path:
Accessibility
--> VoiceOver
--> Speech
当我们按下后退按钮时,我们会遵循相同的路由路径,但方向相反。线性路由很有用,因为它允许简单且可预测的路由行为。
¥When we press the back button, we follow that same routing path except in reverse. Linear routing is helpful in that it allows for simple and predictable routing behaviors.
线性路由的缺点是它不允许复杂的用户体验,例如选项卡视图。这就是非线性路由发挥作用的地方。
¥The downside of linear routing is that it does not allow for complex user experiences such as tab views. This is where non-linear routing comes into play.
非线性路由
¥Non-Linear Routing
对于许多学习使用 Ionic 构建移动应用的 Web 开发者来说,非线性路由可能 是一个新概念。
¥Non-linear routing is a concept that may be new to many web developers learning to build mobile apps with Ionic.
非线性路由意味着用户应该返回的视图不一定是屏幕上显示的前一个视图。
¥Non-linear routing means that the view that the user should go back to is not necessarily the previous view that was displayed on the screen.
以下是非线性路由的示例:
¥The following is an example of non-linear routing:
在上面的示例中,我们从 Originals
选项卡开始。点击卡片即可进入 Originals
选项卡中的 Ted Lasso
视图。
¥In the example above, we start on the Originals
tab. Tapping a card brings us to the Ted Lasso
view within the Originals
tab.
从这里,我们切换到 Search
选项卡。然后,我们再次点击 Originals
选项卡,返回到 Ted Lasso
视图。至此,我们已经开始使用非线性路由。
¥From here, we switch to the Search
tab. Then, we tap the Originals
tab again and are brought back to the Ted Lasso
view. At this point, we have started using non-linear routing.
为什么这是非线性路由?我们之前看到的视图是 Search
视图。然而,按 Ted Lasso
视图上的后退按钮应该会让我们回到根 Originals
视图。发生这种情况是因为移动应用中的每个选项卡都被视为自己的堆栈。使用选项卡 部分对此进行了更详细的讨论。
¥Why is this non-linear routing? The previous view we were on was the Search
view. However, pressing the back button on the Ted Lasso
view should bring us back to the root Originals
view. This happens because each tab in a mobile app is treated as its own stack. The Working with Tabs sections goes over this in more detail.
如果从 Ted Lasso
视图中点击简单地称为 history.go(-1)
的后退按钮,我们将返回到 Search
视图,这是不正确的。
¥If tapping the back button simply called history.go(-1)
from the Ted Lasso
view, we would be brought back to the Search
view which is not correct.
非线性路由允许线性路由无法处理的复杂用户流。然而,某些线性路由 API(例如 history.go()
)不能在这种非线性环境中使用。这意味着在使用选项卡或嵌套插座时不应使用 history.go()
。
¥Non-linear routing allows for sophisticated user flows that linear routing cannot handle. However, certain linear routing APIs such as history.go()
cannot be used in this non-linear environment. This means that history.go()
should not be used when using tabs or nested outlets.
我应该选择哪一个?
¥Which one should I choose?
我们建议你的应用尽可能简单,直到你需要添加非线性路由。非线性路由非常强大,但它也给移动应用增加了相当多的复杂性。
¥We recommend keeping your application as simple as possible until you need to add non-linear routing. Non-linear routing is very powerful, but it also adds a considerable amount of complexity to mobile applications.
非线性布线的两个最常见用途是使用制表符和嵌套 IonRouterOutlets
。如果你的应用满足选项卡或嵌套路由出口用例,我们建议仅使用非线性路由。
¥The two most common uses of non-linear routing is with tabs and nested IonRouterOutlets
. We recommend only using non-linear routing if your application meets the tabs or nested router outlet use cases.
有关选项卡的更多信息,请参阅 使用选项卡。
¥For more on tabs, please see Working with Tabs.
有关嵌套路由插座的更多信息,请参阅 嵌套路由。
¥For more on nested router outlets, please see Nested Routes.
共享 URL 与嵌套路由
¥Shared URLs versus Nested Routes
设置路由时一个常见的混淆点是在共享 URL 或嵌套路由之间做出选择。本指南的这一部分将解释两者并帮助你决定使用哪一个。
¥A common point of confusion when setting up routing is deciding between shared URLs or nested routes. This part of the guide will explain both and help you decide which one to use.
共享网址
¥Shared URLs
共享 URL 是一种路由配置,其中路由具有公共的 URL 片段。以下是共享 URL 配置的示例:
¥Shared URLs is a route configuration where routes have pieces of the URL in common. The following is an example of a shared URL configuration:
const App: React.FC = () => (
<IonApp>
<IonReactRouter>
<IonRouterOutlet>
<Route path="/dashboard" exact={true}>
<DashboardMainPage />
</Route>
<Route path="/dashboard/stats" exact={true}>
<DashboardStatsPage />
</Route>
</IonRouterOutlet>
</IonReactRouter>
</IonApp>
);
上述路由被视为 "shared",因为它们重用了 URL 的 dashboard
部分。
¥The above routes are considered "shared" because they reuse the dashboard
piece of the URL.
嵌套路由
¥Nested Routes
嵌套路由是一种路由配置,其中路由被列为其他路由的子路由。以下是嵌套路由配置的示例:
¥Nested Routes is a route configuration where routes are listed as children of other routes. The following is an example of a nested route configuration:
const App: React.FC = () => (
<IonApp>
<IonReactRouter>
<IonRouterOutlet>
<Route path="/dashboard/:id">
<DashboardRouterOutlet />
</Route>
</IonRouterOutlet>
</IonReactRouter>
</IonApp>
);
const DashboardRouterOutlet: React.FC = () => (
<IonRouterOutlet>
<Route path="/dashboard" exact={true}>
<DashboardMainPage />
</Route>
<Route path="/dashboard/stats" exact={true}>
<DashboardStatsPage />
</Route>
</IonRouterOutlet>
);
上述路由是嵌套的,因为它们位于父路由的 children
数组中。请注意,父路由渲染 DashboardRouterOutlet
组件。当你嵌套路由时,你需要渲染 IonRouterOutlet
的另一个实例。
¥The above routes are nested because they are in the children
array of the parent route. Notice that the parent route renders the DashboardRouterOutlet
component. When you nest routes, you need to render another instance of IonRouterOutlet
.
我应该选择哪一个?
¥Which one should I choose?
当你想要从页面 A 转换到页面 B 同时保留 URL 中两个页面之间的关系时,共享 URL 非常有用。在我们前面的示例中,/dashboard
页面上的按钮可以转换到 /dashboard/stats
页面。由于 a) 页面转换和 b) url,两个页面之间的关系得以保留。
¥Shared URLs are great when you want to transition from page A to page B while preserving the relationship between the two pages in the URL. In our previous example, a button on the /dashboard
page could transition to the /dashboard/stats
page. The relationship between the two pages is preserved because of a) the page transition and b) the url.
当你想要渲染插座 A 中的内容同时渲染嵌套插座 B 内的子内容时,应使用嵌套路由。你将遇到的最常见的用例是选项卡。当你加载选项卡 Ionic 入门应用时,你将看到第一个 IonRouterOutlet
中渲染的 IonTabBar
和 IonTabs
组件。IonTabs
组件渲染另一个 IonRouterOutlet
,它负责渲染每个选项卡的内容。
¥Nested routes should be used when you want to render content in outlet A while also rendering sub-content inside of a nested outlet B. The most common use case you will run into is tabs. When you load up a tabs Ionic starter application, you will see IonTabBar
and IonTabs
components rendered in the first IonRouterOutlet
. The IonTabs
component renders another IonRouterOutlet
which is responsible for rendering the contents of each tab.
嵌套路由在移动应用中有意义的用例很少。如有疑问,请使用共享 URL 路由配置。我们强烈警告不要在选项卡以外的上下文中使用嵌套路由,因为它很快就会使你的应用导航变得混乱。
¥There are very few use cases in which nested routes make sense in mobile applications. When in doubt, use the shared URL route configuration. We strongly caution against using nested routing in contexts other than tabs as it can quickly make navigating your app confusing.
使用选项卡
¥Working with Tabs
使用选项卡时,Ionic 需要一种方法来知道哪个视图属于哪个选项卡。IonTabs
组件在这里派上用场,但让我们看看它的路由设置是什么样的:
¥When working with tabs, Ionic needs a way to know which view belongs to which tab. The IonTabs
component comes in handy here, but let's look at what the routing setup for this looks like:
<IonApp>
<IonReactRouter>
<IonRouterOutlet>
<Route path="/tabs" render={() =>
<Tabs />
} />
<Route exact path="/">
<Redirect to="/tabs" />
</Route>
</IonRouterOutlet>
</IonReactRouter>
</IonApp>
在这里,我们的 tabs
路径加载了 Tabs
组件。我们提供每个选项卡作为该组件内部的路由对象。在此示例中,我们将路径称为 tabs
,但这可以自定义。
¥Here, our tabs
path loads a Tabs
component. We provide each tab as a route object inside of this component. In this example, we call the path tabs
, but this can be customized.
让我们首先看一下我们的 Tabs
组件:
¥Let's start by taking a look at our Tabs
component:
import { Redirect, Route } from 'react-router-dom';
import { IonIcon, IonLabel, IonRouterOutlet, IonTabBar, IonTabButton, IonTabs } from '@ionic/react';
import { IonReactRouter } from '@ionic/react-router';
import { ellipse, square, triangle } from 'ionicons/icons';
import Tab1 from './pages/Tab1';
import Tab2 from './pages/Tab2';
import Tab3 from './pages/Tab3';
const Tabs: React.FC = () => (
<IonTabs>
<IonRouterOutlet>
<Redirect exact path="/tabs" to="/tabs/tab1" />
<Route exact path="/tabs/tab1">
<Tab1 />
</Route>
<Route exact path="/tabs/tab2">
<Tab2 />
</Route>
<Route path="/tabs/tab3">
<Tab3 />
</Route>
<Route exact path="/tabs">
<Redirect to="/tabs/tab1" />
</Route>
</IonRouterOutlet>
<IonTabBar slot="bottom">
<IonTabButton tab="tab1" href="/tabs/tab1">
<IonIcon icon={triangle} />
<IonLabel>Tab 1</IonLabel>
</IonTabButton>
<IonTabButton tab="tab2" href="/tabs/tab2">
<IonIcon icon={ellipse} />
<IonLabel>Tab 2</IonLabel>
</IonTabButton>
<IonTabButton tab="tab3" href="/tabs/tab3">
<IonIcon icon={square} />
<IonLabel>Tab 3</IonLabel>
</IonTabButton>
</IonTabBar>
</IonTabs>
);
export default Tabs;
如果你以前使用过 Ionic Framework,那么这应该感觉很熟悉。我们创建一个 IonTabs
组件并提供一个 IonTabBar
。IonTabBar
提供 IonTabButton
组件,每个组件都有一个 tab
属性,该属性与其在路由配置中的相应选项卡关联。我们还提供了 IonRouterOutlet
来为 IonTabs
提供渲染不同选项卡视图的出口。
¥If you have worked with Ionic Framework before, this should feel familiar. We create an IonTabs
component and provide an IonTabBar
. The IonTabBar
provides IonTabButton
components, each with a tab
property that is associated with its corresponding tab in the router config. We also provide an IonRouterOutlet
to give IonTabs
an outlet to render the different tab views in.
IonTabs
为你渲染了一个 IonPage
,所以你不需要在这里手动添加 IonPage
。
¥IonTabs
renders an IonPage
for you, so you do not need to add IonPage
manually here.
Ionic 中的选项卡工作原理
¥How Tabs in Ionic Work
Ionic 中的每个选项卡都被视为一个单独的导航堆栈。这意味着如果你的应用中有三个选项卡,则每个选项卡都有自己的导航堆栈。在每个堆栈中,你可以向前导航(推送视图)和向后导航(弹出视图)。
¥Each tab in Ionic is treated as an individual navigation stack. This means if you have three tabs in your application, each tab has its own navigation stack. Within each stack you can navigate forwards (push a view) and backwards (pop a view).
请务必注意此行为,因为它与其他基于 Web UI 库中的大多数选项卡实现不同。其他库通常将选项卡作为一个历史堆栈进行管理。
¥This behavior is important to note as it is different than most tab implementations that are found in other web based UI libraries. Other libraries typically manage tabs as one single history stack.
由于 Ionic 专注于帮助开发者构建移动应用,因此 Ionic 中的选项卡旨在尽可能匹配原生移动选项卡。因此,Ionic 选项卡中的某些行为可能与你在其他 UI 库中看到的选项卡实现不同。请继续阅读以了解有关其中一些差异的更多信息。
¥Since Ionic is focused on helping developers build mobile apps, the tabs in Ionic are designed to match native mobile tabs as closely as possible. As a result, there may be certain behaviors in Ionic's tabs that differ from tabs implementations you have seen in other UI libraries. Read on to learn more about some of these differences.