Vue 0基础学习路线(21)—— 图解深度详述vue的路由重定向及组件、详细地路由配置和路由取别名和添加404路由页面及详细案例(附详细案例代码解析过程及版本迭代过程)- 求解决重定向高亮失效的问题

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: branch05

commit 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: branch05

commit 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: branch05

commit 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,看到详细版本修改过程,搭配博客学习。



(后续待补充)

猜你喜欢

转载自blog.csdn.net/u013946061/article/details/107804712
今日推荐