Router路由

suaxi
2022-07-17 / 0 评论 / 35 阅读 / 正在检测是否收录...

概念:一个路由(route)就是一组映射关系(key - value,key为路径,value为组件)

,多个路由需要路由器(router)进行管理

1. 基本使用

(1)安装(以vue2为例):npm i vue-router@3

(2)使用插件:Vue.use(VueRouter)

(3)路由配置:

//路由配置
import VueRouter from 'vue-router'
import About from '@/components/About'
import Home from '@/components/Home'

export default new VueRouter( {
    routes: [
        {
            path: '/about',
            component: About
        },
        {
            path: '/about',
            component: Home
        }
    ]
})

(3)路由切换:

<router-link class="list-group-item" active-class="active" to="/about">About</router-link>

(4)指定页面展示位置:

<router-view></router-view>

2. 几个注意点

(1)路由组件一般放在views文件夹,一般组件放在components文件夹

(2)通过切换,“隐藏”了的路由组件会被销毁,需要的时候再挂载

(3)每个路由组件都有自己的$route属性,存储对应的路由信息;

(4)整个应用只有一个router

3. 嵌套路由

(1)使用children配置项:

export default new VueRouter( {
    routes: [
        {
            path: '/about',
            component: About
        },
        {
            path: '/home',
            component: Home,
            children: [
                {
                    //子路由之前不写左斜杠“/”
                    path: 'news',
                    component: News
                },
                {
                    path: 'message',
                    component: Message
                }
            ]
        }
    ]
})

(2)跳转(要写全路径)

<router-link class="list-group-item" to="/home/news">News</router-link>

4. 路由的query参数

(1)传递参数

<!-- 跳转路由并携带query参数,to的字符串写法 -->
<router-link :to="`/home/message/detail?id=${m.id}&title=${m.title}`">{{m.title}}</router-link>

<!-- 跳转路由并携带query参数,to的对象写法 -->
<router-link :to="{
    path: '/home/message/detail',
    query: {
        id: m.id,
        title: m.title
        }
    }">
    {{m.title}}
</router-link>

(2)接收参数

this.$route.query.id
this.$route.query.title

5. 命名路由

(1)作用:简化路由的跳转

(2)基本使用:

  • 命名

    {
        path: '/home',
        component: Home,
        children: [
            {
                //子路由之前不写左斜杠“/”
                path: 'news',
                component: News
            },
            {
                path: 'message',
                component: Message,
                children: [
                    {
                        name: 'detail',
                        path: 'detail',
                        component: Detail,
                    }
                ]
            }
        ]
    }
  • 简化跳转

    <!-- 简化前 -->
    <router-link to="/home/message/detail">详情</router-link>
    
    <!-- 简化后,直接通过名字跳转 -->
    <router-link :to="{name:'detail'}">详情</router-link>
    
    <!-- 简化写法携带参数 -->
    <router-link :to="{
      name: 'detail',
      query: {
      id: m.id,
      title: m.title
      }
    }">详情</router-link>

6. 路由的params参数

(1)配置路由,声明接收params参数

{
    path: '/home',
    component: Home,
    children: [
        {
            //子路由之前不写左斜杠“/”
            path: 'news',
            component: News
        },
        {
            path: 'message',
            component: Message,
            children: [
                {
                    name: 'detail',
                    //使用占位符声明接收params参数
                    path: 'detail/:id/:title',
                    component: Detail,
                }
            ]
        }
    ]
}

(2)传递参数(携带params时,必须使用路由名字,不能使用路径)

<!-- 跳转路由并携带params参数,to的字符串写法 -->
<!-- <router-link :to="`/home/message/detail/${m.id}/${m.title}`">详情</router-link> -->

<!-- 跳转路由并携带params参数,to的对象写法 -->
<router-link :to="{
  name: 'detail',
  //携带params时,必须使用路由名字,不能使用路径
  params: {
  id: m.id,
  title: m.title
  }
}">详情</router-link>

(3)接收参数

this.$route.params.id
this.$route.params.title

7. 路由的props参数

作用:方便路由组件接收参数

{
    path: 'message',
    component: Message,
    children: [
        {
            name: 'detail',
            path: 'detail',
            component: Detail,
            //props的第一种写法,值为对象,该对象中的所有key-value都会以props的形式传给Detail组件
            //props: {a:1,b:"B"}

            //props的第二种写法,值为布尔值,若值位真,就会把该路由组件收到的所有params参数,以props的形式传给Detail组件
            //props: true

            //props的第三种写法,值为函数
            /* props({$route}) {
                                return {
                                    id: $route.query.id,
                                    title: $route.query.title,
                                }
                            } */

            //简写
            props({query:{id,title}}) {
                return {
                    id,title
                }
            }
        }
    ]
}

8. <router-link>的replace属性

(1)作用:控制路由跳转时操作浏览器历史记录的模式

(2)浏览器历史记录有两种写入方式(默认为push):

  • push:追加历史记录
  • replace:替换当前记录

(3)使用:<router-link replace></router-link>

9. 编程式路由导航

(1)作用:不借助<router-link>实现路由跳转

(2)使用:

<!-- push -->
this.$router.push({
    name: 'detail',
    query: {
        id: m.id,
        title: m.title
    }
})

<!-- replace -->
    this.$router.replace({
    name: 'detail',
    query: {
        id: m.id,
        title: m.title
    }
})

<!-- 前进 -->
this.$router.back()

<!-- 后退 -->
this.$router.forward()

<!-- 前进/后退x步(x步长) -->
this.$router.go(x)

10. 缓存路由组件

(1)作用:让不展示的路由组件保持挂载,不销毁

(2)使用:

<!--1.考虑要缓存的路由在哪个组件展示
    2.include写的必须是组件名
    3.缓存多个组件时使用双向绑定和数组形式即可,:inclue="['x','y']"
-->
<keep-alive include="MyNews">
    <router-view></router-view>
</keep-alive>

11. 两个新的生命周期钩子

(1)作用:路由组件所独有,用于捕获路由组件的激活状态

(2)activated:路由组件激活时被触发

deactivated:反之,路由组件失活时被触发

(3)标题淡化Demo:

//激活
activated() {
    console.log('News组件激活')
    this.timer = setInterval(() => {
        console.log('@')
        this.opacity -= 0.01
        if (this.opacity <= 0) {
            this.opacity = 1
        }
    })
},

//失活
deactivated() {
    console.log('News组件失活')
    clearInterval(this.timer)
}

12. 路由守卫

(1)作用:对路由进行权限控制

(2)分类:全局、独享、组件内守卫

(3)全局守卫

//全局前置路由守卫,初始化及每次路由切换之前被调用
router.beforeEach((to, from, next) => {
    console.log('前置路由守卫', to, from)
    //鉴权
    if (to.meta.isAuth) {
        if (localStorage.getItem('token') === '1') {
            next()
        } else {
            alert('暂无查看权限!')
        }
    } else {
        next()
    }
})

//全局后置路由守卫,初始化及每次路由切换之后被调用
router.afterEach((to, from) => {
    console.log('后置路由守卫', to, from)
    document.title = to.meta.title || 'Vue2 Demo'
})

(4)独享路由守卫

beforeEnter(to,from,next) {
    console.log('独享路由守卫', to, from)
    //鉴权
    if (to.meta.isAuth) {
        if (localStorage.getItem('token') === '1') {
            next()
        } else {
            alert('暂无查看权限!')
        }
    } else {
        next()
    }
}

(5)组件内守卫

//通过路由规则,进入该组件时被调用
beforeRouteEnter(to, from, next) {
    console.log('About组件beforeRouteEnter', to, from)
    //鉴权
    if (to.meta.isAuth) {
        if (localStorage.getItem('token') === '1') {
            next()
        } else {
            alert('暂无查看权限!')
        }
    } else {
        next()
    }
},

//通过路由规则,离开该组件时被调用
beforeRouteLeave(to, from, next) {
    console.log('About组件beforeRouteLeave', to, from)
    next()
}

13. 路由器的两种工作模式

(1)hash值:#号及其后面的内容

(2)hash值不会包含在HTTP请求中,即hash值不会带给后台服务器

(3)hashhistory的区别:

  • hash值地址栏会带着#号,兼容性好
  • history模式地址干净美观,兼容性相较于hash略差,项目上线部署时需解决刷新404的问题
0

评论 (0)

取消