API 浏览器
使用布局和页面进行路由

在使用 Quasar 布局构建路由时,你可以从 Vue Router 的功能中受益。以下信息仅供参考,并非强制要求。Quasar 为你提供充分的自由。以下仅作为示例。

¥You can benefit from Vue Router’s capabilities while structuring your routes with a Quasar Layout. The information below is just a recommendation and not mandatory to follow. Quasar allows you full freedom. Take the lines below only as an example.

QLayout 是用于封装页面的组件,以便多个页面可以共享相同的页眉、抽屉等。然而,你也可以配置每个页面的页眉/页脚/抽屉,但它们都必须是 QLayout 组件的子组件。为了理解其工作原理,你需要阅读一些关于 Vue Router 嵌套路由 的内容。

¥QLayout is the component used to encapsulate pages, so that multiple pages will share the same header, drawers and so on. However, you can also configure per page header/footer/drawers, but they all must be children of the QLayout component. In order to understand how this works, you need a little bit of reading on Vue Router nested routes.

为了更清楚地说明,我们举个例子。我们有一个布局(‘user’)和两个页面(‘user-feed’ 和 ‘user-profile’)。我们希望像这样配置网站/应用路由:/user/feed/user/profile

¥To make it more clear, let’s take an example. We have one layout (‘user’) and two pages (‘user-feed’ and ‘user-profile’). We want to configure the website/app routes like this: /user/feed and /user/profile.

创建文件(Creating Files)

¥Creating Files

Quasar 不强制使用特定的文件夹结构。以下只是一个例子。你可以将布局和页面放在一个文件夹中,或者将页面放在你选择的特定文件夹结构中,或者创建你自己的布局和页面文件夹。对于 Quasar 来说,这无关紧要。重要的是在 /src/router/routes.js 中正确引用它们。

¥Quasar does not enforce a specific folder structure. The following is just an example. You can put layouts and pages together in a folder, or put pages in your specific folder structure of choice, or create your own layout and page folders. It doesn’t matter for Quasar. All that matters is that you reference them correctly in /src/router/routes.js.

让我们创建布局和页面文件。你可以使用 Quasar CLI 的辅助命令,也可以直接自行创建。

¥Let’s create the layout and page files. You can use a helper command of Quasar CLI or simply create them yourself.

$ quasar new layout User
 app:new Generated layout: src/layouts/User.vue +0ms
 app:new Make sure to reference it in src/router/routes.js +2ms

$ quasar new page Profile Posts
 app:new Generated page: src/pages/Profile.vue +0ms
 app:new Make sure to reference it in src/router/routes.js +2ms

 app:new Generated page: src/pages/Posts.vue +1ms
 app:new Make sure to reference it in src/router/routes.js +0ms

上述命令创建以下文件夹结构:

¥The commands above create the following folder structure:

User.vue
# our QLayout definition
Posts.vue
# page for /user/feed route
Profile.vue
# page for /user/profile route

定义路由(Defining Routes)

¥Defining Routes

你的页面 (/src/pages) 和布局 (/src/layouts) 会通过 /src/router/routes.js 中的 Vue Router 注入到你的网站/应用中(并进行管理)。每个页面和布局都需要在那里引用。

¥Your Pages (/src/pages) and Layouts (/src/layouts) are injected into your website/app (and also managed) through Vue Router in /src/router/routes.js. Each Page and Layout needs to be referenced there.

routes.js 使用延迟加载的示例:

¥Example of routes.js using lazy-loading:

// we define our routes in this file

const routes = [
  {
    path: '/',
    component: () => import('pages/Landing')
  }
]

export default routes

routes.js 使用预先加载的示例:

¥Example of routes.js using eager loading:

// we define our routes in this file

import LandingPage from 'pages/Landing'

const routes = [
  {
    path: '/',
    component: LandingPage
  }
]

export default routes

提示

更深入地分析使用 @quasar/app-vite@quasar/app-webpack 的延迟加载/代码拆分。

¥More in-depth analysis of Lazy loading / code-splitting with @quasar/app-vite or @quasar/app-webpack.

提示

配置路由以使用布局和页面基本上包括正确嵌套路由,我们将在下一节中看到。

¥Configuring routes to use Layouts and Pages basically consists of correctly nesting routes, as we’ll see in the next section.

嵌套路由(Nested Routes)

¥Nested Routes

实际应用的 UI 通常由多层嵌套的组件组成。URL 的各个部分通常对应于某种嵌套组件结构,例如:

¥Real app UIs are usually composed of components that are nested multiple levels deep. It is also very common that the segments of a URL corresponds to a certain structure of nested components, for example:

/user/profile                   /user/posts
+------------------+            +-----------------+
| User             |            | User            |
| +--------------+ |            | +-------------+ |
| | Profile      | |  +------>  | | Posts       | |
| |              | |            | |             | |
| +--------------+ |            | +-------------+ |
+------------------+            +-----------------+

使用 Vue Router,使用嵌套路由配置来表达这种关系非常简单。我们注意到一些事情:两个页面都需要由用户组件封装。嘿,用户组件现在是一个布局!

¥With Vue Router, it is very simple to express this relationship using nested route configurations. We notice some things: both pages need to be wrapped by a User component. Hey, User component is then a Layout!

由于用户布局封装了内部页面,因此需要一个注入点。这由 <router-view> 组件提供:

¥Since User layout wraps inner pages, they need an injection point. This is supplied by the <router-view> component:

/src/layouts/User.vue

<template>
  <q-layout>
    ...

    <!-- this is where the Pages are injected -->
    <q-page-container>
      <router-view></router-view>
    </q-page-container>

    ...
  </q-layout>
</template>
/src/pages/Profile.vue or Posts.vue

<template>
  <q-page>
    ...page content...
  </q-page>
</template>

我们的示例指定了一些路由(/user/profile 和 /user/posts)。那么,我们现在该如何整合所有内容呢?我们编辑 routes 文件。我们将在这里配置路由,指定哪些组件是布局,哪些是页面,并将它们引用/导入到我们的应用中:

¥Our example has some routes specified (/user/profile and /user/posts). So how can we put everything together now? We edit the routes file. That’s where we will configure routes, tell which components are Layouts and which are Pages and also reference/import them into our app:

src/router/routes.js

import User from 'layouts/User'
import Profile from 'pages/Profile'
import Posts from 'pages/Posts'

const routes = [
  {
    path: '/user',

    // we use /src/layouts/User component which is imported above
    component: User,

    // hey, it has children routes and User has <router-view> in it;
    // It is really a Layout then!
    children: [
      // Profile page
      {
        path: 'profile', // here it is, route /user/profile
        component: Profile // we reference /src/pages/Profile.vue imported above
      },

      // Posts page
      {
        path: 'posts', // here it is, route /user/posts
        component: Posts // we reference /src/pages/Posts.vue imported above
      }
    ]
  }
]

export default routes

警告

请注意,以 / 开头的嵌套路径将被视为根路径。这允许你利用组件嵌套,而无需使用嵌套 URL。

¥Note that nested paths that start with / will be treated as a root path. This allows you to leverage component nesting without having to use a nested URL.

我们的路由配置 (/src/router/routes.js) 应该如下所示:

¥Our routes configuration (/src/router/routes.js) should look like this:

export default [
  {
    path: '/user',

    // We point it to our component
    // where we defined our QLayout
    component: () => import('layouts/user'),

    // Now we define the sub-routes.
    // These are getting injected into
    // layout (from above) automatically
    // by using <router-view> placeholder
    // (need to specify it in layout)
    children: [
      {
        path: 'feed',
        component: () => import('pages/user-feed')
      },
      {
        path: 'profile',
        component: () => import('pages/user-profile')
      }
    ]
  }
]

请注意以下几点:

¥Please notice a few things:

  • 我们使用布局和页面的延迟加载(() => import(<path>))。如果你的网站/应用规模较小,那么你可以忽略延迟加载的优势,因为它们可能会增加不必要的开销:

    ¥We are using lazy loading of layouts and pages (() => import(<path>)). If your website/app is small, then you can skip the lazy loading benefits as they could add more overhead than what it’s worth:

    import UserLayout from 'layouts/user'
    import UserFeed from 'pages/user-feed'
    import UserProfile from 'pages/user-profile'
    
    export default [
      path: '/user',
      component: UserLayout,
      children: [
        { path: 'feed', component: UserFeed },
        { path: 'profile', component: UserProfile }
      ]
    ]
  • Quasar 提供了一些开箱即用的 Webpack 别名(‘layouts’ 指向 ‘/src/layouts’,‘pages’ 指向 ‘/src/pages’),这些别名已在上例中使用。

    ¥Quasar provides some out of the box Webpack aliases (‘layouts’ which points to ‘/src/layouts’ and ‘pages’ which points to ‘/src/pages’), which are used in the above examples.

  • 布局的页面在 Vue Router 配置中声明为其子级,以便 <router-view/> 知道要注入哪个页面组件。请记住,只要你的布局包含页面,就始终使用此 Vue 组件。

    ¥Pages of a Layout are declared as children of it in the Vue Router configuration so that <router-view/> will know what page component to inject. Remember to always use this Vue component whenever your Layout has pages attached to it.

    <q-layout>
      ...
      <q-page-container>
        <!--
          This is where your pages will get
          injected into your Layout
        -->
        <router-view />
      </q-page-container>
      ...
    </q-layout>

提示

请查看 Vue 路由 文档,以全面理解上述示例以及如何为你的应用配置路由及其路由。

¥Please check Vue Router documentation to fully understand the examples above and how to configure the router and its routes for your app.