vue-router安装已经说完了,基本使用也说完了,那么接下来就该开始了解里面的一些特殊用法了。
在创建路由器实例时,history 配置允许我们在不同的历史模式中进行选择。
const router = new VueRouter({
routes,
mode:'hash' //默认可以不写
})
它在内部传递的实际 URL 之前使用了一个哈希字符(#)。由于这部分 URL 从未被发送到服务器,所以它不需要在服务器层面上进行任何特殊处理。不过,它在 SEO 中确实有不好的影响。如果你担心这个问题,可以使用 HTML5 模式。
const router = new VueRouter({
routes,
mode:'history'
})
当使用这种历史模式时,URL 会看起来很 "正常",例如 https://example.com/user/id。
路由匹配方式也有很多
{
path: '/',
name: 'home',
component: HomeView
},
向这样的固定地址路径的方式就是静态匹配。
const routes = [
// 动态字段以冒号开始
{ path: '/users/:id', component: HomeView },
]
动态匹配中的动态字段使用 :+字段 的方式来匹配
TIP:当一个路由被匹配时,它的 params 的值将在每个组件中以 this.$route.params 的形式暴露出来。因此,我们可以通过 {{ $route.params.id }} 来显示动态路径内容
Vue-router并不支持nignx那样的完全正则的方式,只能通过正则限制动态字段的方式
const routes = [
// /:orderId -> 仅匹配数字
{ path: '/:orderId(\\d+)' },
// /:productName -> 匹配其他任何内容
{ path: '/:productName' },
]
上面案例中,orderId只匹配纯数字的地址。
TIP:确保转义反斜杠( \ ),就像我们对 \d (变成\\d)所做的那样,在 JavaScript 中实际传递字符串中的反斜杠字符。
const routes = [
// /:chapters -> 匹配 /one, /one/two, /one/two/three, 等
{ path: '/:chapters+' },
// /:chapters -> 匹配 /, /one, /one/two, /one/two/three, 等
{ path: '/:chapters*' },
/ /:chapters -> 匹配 /, /one
{ path: '/:chapters?' },
/ /:orderId -> 匹配 /, /55
{ path: '/:orderId(\\d+)?' },
]
“+” 匹配1次或多次,“*”匹配0次或多次,“?”匹配0次或1次,“(\d+)?”匹配数字0次或1次
后台网址重定向一般都是通过apache或nginx来完成的,前台同样也可以完成重定向任务。
重定向的目标可以是一个地址
const routes = [
{
path:'/hh',
redirect:'/' //地址'/hh' 路由重定向到 '/'
},
]
也可以是一个路由
const routes = [
{
path:'/hhh',
redirect:{name:'about'} //地址'hhh'重定向到路由about
},
{
path: '/about',
name: 'about',
//动态导入,当路由被访问的时候才加载对应组件,这样就会更加高效。
component: () => import(/* webpackChunkName: "about" */ '../views/AboutView.vue')
}
]
使用方法来重定向
const routes = [
{
// /search/screens -> /search?q=screens
path: '/search/:searchText',
redirect: to => {
// 方法接收目标路由作为参数
// return 重定向的字符串路径/路径对象
return { path: '/search', query: { q: to.params.searchText } }
},
}
]
TIP:在写 redirect 的时候,可以省略 component 配置,因为它从来没有被直接访问过,所以没有组件要渲染。唯一的例外是嵌套路由:如果一个路由记录有 children 和 redirect 属性,它也应该有 component 属性。
也可以使用相对位置重定向
const routes = [
{
// 将总是把/users/123/posts重定向到/users/123/profile。
path: '/users/:id/posts',
redirect: to => {
// 该函数接收目标路由作为参数
// 相对位置不以`/`开头
// 或 { path: 'profile'}
return 'profile'
},
},
]
重定向类似网页跳转,用户输入的网址会修改并跳转新地址。我们可以通过使用别名来进行不修改网址,只修改内容的重定向。
{
path:'/aa',
component: HomeView,
alias:'/' //别名'aa' 路由重定向到 '/'
},
通过别名,你可以自由地将 UI 结构映射到一个任意的 URL,而不受配置的嵌套结构的限制。使别名以 / 开头,以使嵌套路径中的路径成为绝对路径。你甚至可以将两者结合起来,用一个数组提供多个别名:
const routes = [
{
path: '/users',
component: UsersLayout,
children: [
// 为这 3 个 URL 呈现 UserList
// - /users
// - /users/list
// - /people
{ path: '', component: UserList, alias: ['/people', 'list'] },
],
},
]
如果你的路由有参数,请确保在任何绝对别名中包含它们:
const routes = [
{
path: '/users/:id',
component: UsersByIdLayout,
children: [
// 为这 3 个 URL 呈现 UserDetails
// - /users/24
// - /users/24/profile
// - /24
{ path: 'profile', component: UserDetails, alias: ['/:id', ''] },
],
},
]
表示目标路由的链接。当被点击后,内部会立刻把 to 的值传到 router。push(),所以这个值可以是一个 string 或者是描述目标位置的对象。
<!-- 字符串 -->
<router-link to="/home">Home</router-link>
<!-- 渲染结果 -->
<a href="/home">Home</a>
<!-- 使用 v-bind 的 JS 表达式 -->
<router-link :to="'/home'">Home</router-link>
<!-- 渲染结果 -->
<a href="/home">Home</a>
<!-- 使用对象 -->
<router-link :to="{ path: '/home' }">Home</router-link>
<!-- 渲染结果 -->
<a href="/home">Home</a>
<!-- 命名的路由 -->
<router-link :to="{ name: 'user', params: { userId: '123' }}">User</router-link>
<!-- 带查询参数,下面的结果为 `/register?plan=private` -->
<router-link :to="{ path: '/register', query: { plan: 'private' }}">Register</router-link>
<!-- 渲染结果 -->
<a href="/register?plan=private"> Register </a>
设置 replace 属性的话,当点击时,会调用 router.replace(),而不是 router.push(),所以导航后不会留下历史记录。
<router-link to="/abc" replace></router-link>
链接激活时,应用于渲染的 <a> 的 class。
默认值:“router-link-active” (或者全局 linkActiveClass)
<router-link to="/" active-class="aa">Home</router-link>
<a href="/" class="aa">Home</a>
当链接激活时,传递给属性 aria-current 的值。
默认值:page
可选值:‘page’ | ‘step’ | ‘location’ | ‘date’ | ‘time’ | ‘true’ | ‘false’ (string)
<router-link to="/" aria-current-value="date">Home</router-link>
<a href="/" aria-current="date">Home</a>
<router-link> 是否应该将其内容包裹在 <a> 元素中。在使用 v-slot 创建自定义 RouterLink 时很有用。默认情况下,<router-link> 会将其内容包裹在 <a> 元素中,即使使用 v-slot 也是如此。传递自定义的 prop,可以去除这种行为。
<router-link to="/home" v-slot="{ route }">
<span>{{ route.fullPath }}</span>
</router-link>
输出:
<a href="/home"><span>/home</span></a>
链接精准激活时,应用于渲染的 <a> 的 class。
默认值:“router-link-exact-active”
<router-link to="/" router-link-exact-active="dd">Home</router-link>
<a href="/" router-link-exact-active="dd">Home</a>
<router-link> 通过一个作用域插槽暴露底层的定制能力。这是一个更高阶的 API,主要面向库作者,但也可以为开发者提供便利,大多数情况下用在一个类似 NavLink 这样的组件里。
TIP:记得把 custom 配置传递给 <router-link>,以防止它将内容包裹在 <a> 元素内。
可选值:
href:解析后的 URL。将会作为一个 <a> 元素的 href 属性。如果什么都没提供,则它会包含 base。
route:解析后的规范化的地址。
navigate:触发导航的函数。 会在必要时自动阻止事件,和 router-link 一样。例如:ctrl 或者 cmd + 点击仍然会被 navigate 忽略。
isActive:如果需要应用 active class,则为 true。允许应用一个任意的 class。
isExactActive:如果需要应用 exact active class,则为 true。允许应用一个任意的 class。
<router-link to="/" custom v-slot="{ href }">
<a :href="href">
<button>自定义</button>
</a>
</router-link>
<a href="/"><button>自定义</button></a>
TIP:如果你在 a 元素上添加一个 target="_blank",你必须省略 @click="navigate" 的处理。
使用 this.$router.push() 来跳转,或者使用this.$router.replace() 无历史跳转
<template>
<div id="app">
<nav>
<router-link to="/">Home</router-link> |
<router-link to="/about">About</router-link> |
<div @click="t">主页</div>
</nav>
<router-view/>
</div>
</template>
<script>
export default {
methods: {
t(){
this.$router.push("/");
}
},
}
</script>