7.命名视图<router-view name="a"></router-view>

395 阅读1分钟

1. <router-view name="a"></router-view>

有时候想同时 (同级) 展示多个视图,而不是嵌套展示

  • 例如创建一个布局,有 sidebar (侧导航) 和 main (主内容) 两个视图,这个时候就可以使用命名视图。你可以在界面中拥有多个单独命名的视图,而不是只有一个单独的出口。如果 router-view 没有设置名字,那么默认为 default
<router-view class="view one"></router-view>
<router-view class="view two" name="a"></router-view>
<router-view class="view three" name="b"></router-view>

2. 对应的components 配置 (带上 s)

  • 一个视图使用一个组件渲染,因此对于同个路由,多个视图就需要多个组件。确保正确使用 components 配置 (带上 s):
const router = new VueRouter({
  routes: [
    {
      path: '/',
      components: {
        default: Foo,
        a: Bar,
        b: Baz
      }
    }
  ]
})

image.png

<!DOCTYPE html>
<html>
  <head>
    <title>vue-router</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.7.8/dist/vue.js"></script>
    <script src="https://unpkg.com/vue-router@3.1.3/dist/vue-router.js"></script>
  </head>
  <body>
    <div id="app">
      <router-view class="view one"></router-view>
      <router-view class="view two" name="a"></router-view>
      <router-view class="view three" name="b"></router-view>
    </div>
    <script>
      const Foo = {
        template: `<div class="Foo">
              <h2>Foo</h2>
            </div>`
      };
      const Bar = {
        template: `<div class="Bar">
              <h2>Bar</h2>
            </div>`
      };
      const Baz = {
        template: `<div class="Baz">
              <h2>Baz</h2>
            </div>`
      };
      const router = new VueRouter({
        routes: [
          {
            path: "/",
            components: {
              default: Foo,
              a: Bar,
              b: Baz
            }
          }
        ]
      });
      const app = new Vue({
        router,
        el: "#app"
      }).$mount("#app");
    </script>
  </body>
</html>

3. 使用命名视图创建嵌套视图

我们也可能使用命名视图创建嵌套视图。这时也需要命名用到的嵌套 router-view 组件。

  • 以一个设置面板为例:
/settings/emails                                       /settings/profile
+-----------------------------------+                  +------------------------------+
| UserSettings                      |                  | UserSettings                 |
| +-----+-------------------------+ |                  | +-----+--------------------+ |
| | Nav | UserEmailsSubscriptions | |  +------------>  | | Nav | UserProfile        | |
| |     +-------------------------+ |                  | |     +--------------------+ |
| |     |                         | |                  | |     | UserProfilePreview | |
| +-----+-------------------------+ |                  | +-----+--------------------+ |
+-----------------------------------+                  +------------------------------+
  • Nav 只是一个常规组件。
  • UserSettings 是一个视图组件。
  • UserEmailsSubscriptionsUserProfileUserProfilePreview 是嵌套的视图组件。

UserSettings 组件的 <template> 部分应该是类似下面的这段代码:

<!-- UserSettings.vue -->
<div>
  <h1>User Settings</h1>
  <NavBar/>
  <router-view/>
  <router-view name="helper"/>  
</div>

然后你可以用这个路由配置完成该布局:

{
  path: '/settings',
  // 你也可以在顶级路由就配置命名视图
  component: UserSettings,
  children: [{
    path: 'emails',
    component: UserEmailsSubscriptions
  }, {
    path: 'profile',
    components: {
      default: UserProfile,
      helper: UserProfilePreview
    }
  }]
}

1.gif

<!DOCTYPE html>
<html>
  <head>
    <title>vue-router</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.7.8/dist/vue.js"></script>
    <script src="https://unpkg.com/vue-router@3.1.3/dist/vue-router.js"></script>
  </head>
  <body>
    <div id="app">
      <router-link to="/settings">settings</router-link>
      <router-link to="/settings/emails">settings/emails</router-link>
      <router-link to="/settings/profile">settings/profile</router-link>
      <router-view></router-view>
    </div>
    <script>
      Vue.component("NavBar", {
        template: `<div class="NavBar">
              <h2>NavBar</h2>
            </div>`
      });
      const UserSettings = {
        template: `<div>
          <h1>User Settings</h1>
          <NavBar/>
          <router-view/>
          <router-view name="helper"/>  
        </div>`
      };
      const UserEmailsSubscriptions = {
        template: `<div class="UserEmailsSubscriptions">
              <h2>UserEmailsSubscriptions</h2>
            </div>`
      };
      const UserProfile = {
        template: `<div class="UserProfile">
              <h2>UserProfile</h2>
            </div>`
      };
      const UserProfilePreview = {
        template: `<div class="UserProfilePreview">
              <h2>UserProfilePreview</h2>
            </div>`
      };
      const router = new VueRouter({
        routes: [
          {
            path: "/settings",
            // 你也可以在顶级路由就配置命名视图
            component: UserSettings,
            children: [
              {
                path: "emails",
                component: UserEmailsSubscriptions
              },
              {
                path: "profile",
                components: {
                  default: UserProfile,
                  helper: UserProfilePreview
                }
              }
            ]
          }
        ]
      });
      const app = new Vue({
        router,
        el: "#app"
      }).$mount("#app");
    </script>
  </body>
</html>