声明式导航

路由导航 router-link

在 vue-router 中,除了使用路由实例的实例方法,通过编写代码来实现( 编程式导航 )外,

还可以使用 <router-link>定义导航链接,该组件支持用户在具有路由功能的应用中点击导航。

<router-link to="/login">登录</router-link>
<router-link to="/register">注册</router-link>

[1] to 属性,用于指定目标地址( 一个字符串或是描述目标位置的对象 ),默认渲染成带有正确链接的 <a>标签

<!-- 字符串 -->
  <router-link to="home">Home</router-link>
  <!-- 渲染结果 -->
  <a href="home">Home</a>

  <!-- 简写 v-bind,就像绑定别的属性一样 -->
  <router-link :to="'home'">Home</router-link>
  <!-- 同上 -->
  <router-link :to="{ path: 'home' }">Home</router-link>

  <!-- 命名路由 -->
  # 命名路由,其常见用途是替换 router-link 中的 to 属性,如果不使用命名路由,
  # 由 router-link 中的 to 属性需要设置全路径,不够灵活,且修改时较麻烦。
  # 使用命名路由,只需要使用包含 name 属性的对象即可。
  # 注意,如果设置了默认子路由,则不要在父级路由上设置 name 属性。

  // 这两种方式都会把路由导航到 /user/123 路径
  <router-link :to="{ name: 'user', params: { userId: 123 }}">User</router-link>
  等同于 router.push({ name: 'user', params: { userId: 123 }})

   const router = new VueRouter({
     routes: [
       {
         path: '/user/:userId',
         name: 'user',  // 命名路由
         component: User
       }
     ]
   })

  <!-- 带查询参数,下面的结果为 /register?plan=private -->
  <router-link :to="{ path: 'register', query: { plan: 'private' }}">Register</router-link>

[2] 可以通过配置 tag 属性,生成别的标签

router-link,默认会生成 a 链接。如果想要 router-link 渲染为其他标签,例如 li,可以指定 tag 属性;

<router-link to="/foo" tag="li">foo</router-link>
  <!-- 渲染结果 -->
  <li>foo</li>  // 它同样会监听点击,触发导航

[3] 当目标路由成功激活时,链接元素自动设置一个表示激活的 CSS 类名

默认值为"router-link-active",可以通过路由实例的其他配置 linkActiveClass 来全局配置。

  • 应用场景 1:用来进行高亮显示
// router-link 默认被渲染成 a 标签
<a href="#/register" class="router-link-exact-active router-link-active">注册</a>
// CSS 样式设置
.router-link-active{color:red;font-size:16px;...}
  • 应用场景 2:有时候,要让 "激活时的 CSS 类名" 应用在外层元素,而不是 <a>标签本身,可以用 <router-link>渲染外层元素,包裹着内层的原生 <a>标签:
<router-link tag="li" to="/foo">
  <a>/foo</a>
</router-link>

// 在这种情况下,<a> 将作为真实的链接(它会获得正确的 href 的),而 "激活时的CSS类名" 则设置到外层的 <li>

[4] 其他

  • 无痕浏览 <boolean> replace      // 值默认为 false

当点击时,会调用 router.replace() 而非 router.push(),于是,导航后不会留下 history 记录。

<router-link :to="{ path: '/abc'}" replace></router-link>

  • 基路径设置 <boolean> append                  // 默认为 false

设置 append属性后,则在当前(相对)路径前添加基路径。例如,从 /a导航到一个相对路径 b,如果没有配置 append,则路径为 /b,如果配了,则为 /a/b

<router-link :to="{ path: 'relative/path'}" append></router-link>

  • 是否激活默认类名的依据是:全包含匹配 <boolean> exact         // 默认为 false

如果当前的路径是 /a开头的,那么 <router-link to="/a">也会被设置 CSS 类名。设置根路径,需要将 path 设置为 '/'。但是,按照这个规则,<router-link to="/">将会点亮各个路由。如果需要精确匹配,仅仅匹配 '/',则使用 exact

<!-- 这个链接只会在地址为 / 的时候被激活 -->
  <router-link to="/" exact>
// 代码示例
<p>
    <router-link to="/" exact>index</router-link>
    <router-link to="/foo">Go to Foo</router-link>
    <router-link to="/bar">Go to Bar</router-link>
  </p>
 
const routes = [
  { path: '/', component: Home },
  { path: '/foo', component: Foo },
  { path: '/bar', component: Bar },
]

  • events 声明可以用来触发导航的事件。可以是一个字符串或是一个包含字符串的数组
类型: string | Array<string>
默认值: 'click'

router-view

<router-view>组件是一个 functional 组件,渲染路径匹配到的视图组件。

<router-view>渲染的组件,还可以内嵌自己的 <router-view>,根据嵌套路径,渲染嵌套组件。


[ 命名视图 ]

有时候想同时 (同级)展示多个视图,而不是嵌套展示,例如创建一个布局,有 sidebar (侧导航) 和 main(主内容) 两个视图,可以使用命名视图,可以在界面中拥有多个单独命名的视图,而不是只有一个单独的出口。

  • 一个视图,使用一个组件渲染( 如果 router-view 没有设置名字,那么默认为 default );
  • 对于同个路由,多个视图就需要多个组件,确保正确使用 components 配置 ( 带上 s )
<div id="app">
  <p>
    <router-link to="/" exact>index</router-link>
    <router-link :to="{ name: 'foo' }">Go to Foo</router-link>
    <router-link :to="{ name: 'bar' }">Go to Bar</router-link>
  </p>
  <router-view></router-view>
  <router-view name="side"></router-view>
</div>
const Home = { template: '<div>home</div>' }
const Foo = { template: '<div>Foo</div>'}
const MainBar = { template: '<div>mainBar</div>' }
const SideBar = { template: '<div>sideBar</div>' }
 
const routes = [
  { path: '/', name:'home', component: Home },
  { path: '/foo', name:'foo', component: Foo},
  { path: '/bar', name:'bar', components: {
    default: MainBar,
    side:SideBar
   } },
]