文章目录
1. 重点提炼
- 重定向
- 别名
- 404页面
2. 重定向
有的时候,我们会根据某种需求对用户请求的页面进行重新定位。
重定向也是通过 routes
配置来完成,下面例子是从 /a
重定向到 /b
:
const router = new VueRouter({
routes: [
{
path: '/a', redirect: '/b' }
]
})
重定向的目标也可以是一个命名的路由:
const router = new VueRouter({
routes: [
{
path: '/a', redirect: {
name: 'foo' }}
]
})
甚至是一个方法,动态返回重定向目标:
const router = new VueRouter({
routes: [
{
path: '/a', redirect: to => {
// 方法接收 目标路由 作为参数
// return 重定向的 字符串路径/路径对象
}}
]
})
注意导航守卫并没有应用在跳转路由上,而仅仅应用在其目标上。
2.1 案例
现有一小说网站,提供了 男生频道 和 女生频道 的两个入口,用户首次进入页面的时候,会出现选择,并记住用户的选择,以后该用户进入网站直接根据记录的选择进入对应的频道。
2.1.1 组件
// BookChoose.vue
<template>
<div>
<router-link :to="{name: 'book-boy'}">男生</router-link>
<span> | </span>
<router-link :to="{name: 'book-girl'}">女生</router-link>
</div>
</template>
// BookBoy.vue
<template>
<div>
BookBoy
</div>
</template>
<script>
export default {
name: 'BookBoy',
created() {
localStorage.setItem('book-type', 'book-boy');
}
}
</script>
// BookGirl.vue
<template>
<div>
BookGirl
</div>
</template>
<script>
export default {
name: 'BookGirl',
created() {
localStorage.setItem('book-type', 'book-girl');
}
}
</script>
2.1.2 路由配置
{
path: '/book',
name: 'book',
// redirect: { name: 'book-choose' }
redirect: to => {
let type = localStorage.getItem('book-type')
return {
name: type || 'book-choose' }
}
},
{
path: '/book-choose',
name: 'book-choose',
component: BookChoose
},
{
path: '/book-boy',
name: 'book-boy',
component: BookBoy
},
{
path: '/book-girl',
name: 'book-girl',
component: BookGirl
}
2.1.3 example01
2.1.3.1 example01-1
实现小说页面框子
\app\src\views\Book\BookBoy.vue
<template>
<div>
男生频道
</div>
</template>
<script>
export default {
name: "BookBoy"
}
</script>
<style scoped>
</style>
\app\src\views\Book\BookGirl.vue
<template>
<div>
女生频道
</div>
</template>
<script>
export default {
name: "BookGirl"
}
</script>
<style scoped>
</style>
设置路由
\app\src\router\index.js
import Vue from 'vue';
import VueRouter from 'vue-router';
import Home from '@/views/Home';
import About from '@/views/About';
import Detail from '@/views/Detail';
import User from '@/views/User';
import Login from '@/views/Login';
import Profile from '@/views/User/Profile'
import Cart from '@/views/User/Cart'
import BookChoose from '@/views/BookChoose'
import BookBoy from '@/views/Book/BookBoy'
import BookGirl from '@/views/Book/BookGirl'
Vue.use(VueRouter);
let router = new VueRouter({
mode: 'history',
routes: [
{
path: '/',
name: 'home',
component: Home
},
{
path: '/about',
name: 'about',
component: About
},
{
path: '/view/:id',
name: 'view',
component: Detail
},
{
path: '/user',
name: 'user',
component: User,
children: [
{
// 上一层的path拼到这一层的path,类似层层继承关系
// ''就代表默认路径
path: '',
name: 'userProfile',
component: Profile
},
{
// 上一层的path拼到这一层的path,类似层层继承关系
path: 'cart',
name: 'userCart',
component: Cart
}
]
},
{
path: '/login',
name: 'login',
component: Login
},
{
path: '/book-choose',
name: 'book-choose',
component: BookChoose
},
{
path: '/book-boy',
name: 'book-boy',
component: BookBoy
},
{
path: '/book-girl',
name: 'book-girl',
component: BookGirl
},
]
});
let user = {
id: 1
}
router.beforeEach((to, from, next) => {
// next();
// id为1代表登录,否则为0代表没登录
if (user.id === 0 && to.name === 'user') {
next({
name: 'login'});
} else {
next();
}
});
export default router;
小说页面
\app\src\views\BookChoose.vue
<template>
<div>
<router-link :to="{name: 'book-boy'}">男生</router-link>
<span> | </span>
<router-link :to="{name: 'book-girl'}">女生</router-link>
</div>
</template>
<script>
export default {
name: "BookChoose"
}
</script>
<style scoped>
</style>
首页导航
\app\src\App.vue
<template>
<div id="app">
<h1>我的主页</h1>
<div id="nav">
<router-link exact to="/">Home</router-link>
<span> | </span>
<router-link to="/about">About</router-link>
<span> | </span>
<router-link to="/user">User</router-link>
<span> | </span>
<router-link to="/book-choose">小说</router-link>
<span> | </span>
<router-link to="/login">Login</router-link>
</div>
<hr />
<router-view></router-view>
</div>
</template>
<script>
export default {
name: 'App'
}
</script>
<style>
.router-link-active {
color: red;
}
</style>
参考:https://https://github.com/6xiaoDi/blog-vue-Novice/tree/a2.04
Branch: branch05commit description:a2.04(example01-1——实现小说页面框子)
tag:a2.04
2.1.3.2 example01-2
重定向:这次跳转到小说
,我们选择男生
,下次选择小说
默认男生
界面。
我们需要记录上回选择的内容,可直接用本地存储
即可。
\app\src\views\Book\BookBoy.vue
<template>
<div>
男生频道
</div>
</template>
<script>
export default {
name: "BookBoy",
created() {
localStorage.setItem('book-type', 'book-boy');
}
}
</script>
<style scoped>
</style>
\app\src\views\Book\BookGirl.vue
<template>
<div>
女生频道
</div>
</template>
<script>
export default {
name: "BookGirl",
created() {
localStorage.setItem('book-type', 'book-girl');
}
}
</script>
<style scoped>
</style>
我们可以在``\app\src\views\BookChoose.vue中的
created周期中直接获取本地存储,跳转至本地存的值的
url`即可。
另一种方法是,在路由的index
中搞定,在里增加一个重定向
。
{
path: '/book-choose',
name: 'book-choose',
component: BookChoose,
redirect: {
name: 'book-body' },
}
发现小说
没了,直接就重定向,BookChoose
组件就没有意义了。
即直接给一个组件设置重定向,实际这个组件就没有任何意义了。
参考:https://https://github.com/6xiaoDi/blog-vue-Novice/tree/a2.05
Branch: branch05commit description:a2.05(example01-2——重定向实现页面跳转历史记录,重定向BookChoose组件没有意义)
tag:a2.05
2.1.3.3 example01-3
如果一个组件想重定向的话,必须把选择页(首页导航中的小说
)面留下,因为第一次总是要在这个页面的。
因此我们需要新建一个路由,专门用来重定向。
\app\src\router\index.js
{
// 没有组件,唯一的作用就是重定向用的
path: '/book',
name: 'book',
redirect: {
name: 'book-choose' }
}
\app\src\App.vue
<div id="nav">
<router-link to="/">Home</router-link>
<span> | </span>
<router-link to="/about">About</router-link>
<span> | </span>
<router-link to="/user">User</router-link>
<span> | </span>
<router-link to="/book">小说</router-link>
<span> | </span>
<router-link to="/login">Login</router-link>
</div>
虽然访问的是/book
,但直接重定向到/book-choose
了。
处理重定向逻辑
{
// 没有组件,唯一的作用就是重定向用的
path: '/book',
name: 'book',
// redirect: { name: 'book-choose' },
// 指定回调函数,to指定目的地
redirect: to => {
let type = localStorage.getItem('book-type')
return {
name: type || 'book-choose' }
}
},
参考:https://https://github.com/6xiaoDi/blog-vue-Novice/tree/a2.06
Branch: branch05commit description:a2.06(example01-3——实现重定向实现页面跳转历史记录)
tag:a2.06
3. 别名
重定向,是从一个路由切换到另外一个路由,而别名是不同的路由显示同一个页面(存在两个url
指向一个页面,相当于指针
<C语言>或者引用
<C++>),比如:/user
是用户中心的路由,/member
,我们也可以给这个页面定义另外一个路由,虽然在某些时候,重定向与别名有类似的效果,但是,别名不存在跳转,浏览器地址栏上显示的 URL 并不会切换
{
path: '/user',
alias: '/member'
component: User,
}
3.1 官网解释
“重定向”的意思是,当用户访问 /a
时,URL 将会被替换成 /b
,然后匹配路由为 /b
,那么“别名”又是什么呢?
/a
的别名是 /b
,意味着,当用户访问 /b
时,URL 会保持为 /b
,但是路由匹配则为 /a
,就像用户访问 /a
一样。
const router = new VueRouter({
routes: [
{
path: '/a', component: A, alias: '/b' }
]
})
“别名”的功能让你可以自由地将 UI 结构映射到任意的 URL,而不是受限于配置的嵌套路由结构。
3.2 example02
如给user
取个别名
{
path: '/user',
name: 'user',
alias: '/member',
component: User,
children: [
{
// 上一层的path拼到这一层的path,类似层层继承关系
// ''就代表默认路径
path: '',
name: 'userProfile',
component: Profile
},
{
// 上一层的path拼到这一层的path,类似层层继承关系
path: 'cart',
name: 'userCart',
component: Cart
}
]
},
但是高亮没了!怎么解决?可以看官方文档的路由导航中。
默认情形下,是访问地址与导航选择一一对应时才高亮,而我们a标签的链接是/user
而不是/member
,并不一致,所以class样式
是加不上去的。
参考:https://https://github.com/6xiaoDi/blog-vue-Novice/tree/a2.07
Branch: branch05
commit description:a2.07(example02——别名)
tag:a2.07
mote:以上重定向和重命名都存在丢失样式的问题,小迪暂时未找到合适的解决办法。
4. 404
{
path: '*',
component: NotFound
}
写在最后
小迪就不详述了,NotFound
组件自己写一个404
页面即可。
考虑到在blog中不好体现代码更改的位置,小迪才用github托管代码,大家可以查看github,看到详细版本修改过程,搭配博客学习。
(后续待补充)