• 万字血书Vue—路由


    image
    多个路由通过路由器进行管理。

    前端路由的概念和原理#

    (编程中的)路由(router)就是一组key-value对应关系,分为:后端路由和前端路由

    后端路由指的是:请求方式、请求地址function处理函数之间的对应关系

    在SPA程序中,所有组件的展示和切换都在这唯一的一个页面内完成,此时,不同组件之间的切换需要通过前端路由来实现

    通俗易懂的来说,前端路由是:Hash地址(url中#的部分)与组件之间的对应关系

    前端路由的工作方式#

    • 用户点击了页面上的路由链接
    • 导致了URL地址栏中的Hash值发生了变化
    • 前端路由监听到了Hash地址的变化
    • 前端路由把当前Hash地址对应的组件渲染到浏览器中

    image

    实现简易的前端路由(底层实现原理)#

    App.vue根组件

    
    
    
    
    
    

    vue-router的基本使用#

    vue-router是vue.js官方给出的路由解决方案,它只能结合vue项目进行使用,能够轻松的管理SPA项目中的组件切换。

    二者差异主要是在声明router配置文件上。

    vue-router 3.x的基本使用步骤#

    • 在项目中安装vue-router
    npm install vue-router@3.5.2 -S
    
    • src源代码目录下,新建router/index.js路由模块
    //导入包
    import Vue from 'vue'
    import VueRouter from 'vue-router'
    //插件引入
    Vue.use(VueRouter)
    //创建路由的实例对象
    const router = new VueRouter
    //向外共享
    export default router
    
    • 在入口文件main.js中引入
    import router from '@/router/index.js'
    ......
    new Vue({
        ...
        router:router
        ...
    }).$mount('#app')
    

    vue-router 4.x的基本使用步骤#

    • 在项目中安装vue-router
    npm install vue-router@next -S
    
    • 定义路由组件

    MyHome.vue、MyMovie.vue、MyAbout.vue

    • 声明路由链接占位符

    可以使用标签(会被渲染成a链接)来声明路由链接,并使用标签来声明路由占位符

    
    
    • 创建路由模块

    从项目中创建router.js路由模块,按照以下四步:

    从vue-router中按需导入两个方法

    import { createRouter, createWebHashHistory } from 'vue-router'
    //createRouter方法用于创建路由的实例对象
    //createWebHashHistory用于指定路由的工作方式(hash模式)
    

    导入需要使用路由控制的组件

    import MyHome from './MyHome.vue'
    import MyMovie from './MyMovie.vue'
    import MyAbout from './MyAbout.vue'
    

    创建路由实例对象

    const router = createRouter({
    history: createWebHashHistory(),
    routes: [
      {
          path: '/home', component: MyHome
      },
      {
          path: '/movie', component: MyMovie
      },
      {
          path: '/about', component: MyAbout
      },
    
    ]
    })
    

    向外共享路由实例对象

    export default router
    

    在main.js中导入并挂载路由模块

    import { createApp } from 'vue'
    import App from './App.vue'
    import './index.css'
    
    import router from './components/router'
    
    const app = createApp(App)
    //挂载路由写法
    app.use(router)
    app.mount('#app')
    
    
    • 导入并挂载路由模块

    vue-router的高级用法#

    路由重定向

    指的是:用户在访问地址A的时候,强制用户跳转到地址C,从而展示特点的组件页面

    通过路由规则的redirect属性,指定新的路由地址

    const router = createRouter({
        history: createWebHashHistory(),
        routes: [
            {
                path: '/home', component: MyHome
            },
            {
                path: '/',redirect:'/home' //访问根路径会重定向到home组件
            },
            {
                path: '/movie', component: MyMovie
            },
            {
                path: '/about', component: MyAbout
            },
    
        ]
    })
    
    路由传参

    query参数

    我的
    
                     path:'/about/home/message',
                     query:{
                     	id:123,
                     	title:'abc'
                     }
                   }">
        我的
    
    

    params参数

    声明时:

    path:'/about/home/message/:id/:title'
    
    我的
    
                     name:'my',
                     params:{
                     	id:123,
                     	title:'abc'
                     }
                   }">
        我的
    
    

    this.$route 是路由的"参数对象"

    this.$router 是路由的"导航对象"

    路由高亮
    • 使用默认的高亮class类名

    被激活的路由链接,默认会使用router-link-active的类名,开发者可以使用此类名选择器,为激活的路由链接设置高亮样式

    • 自定义路由高亮的class类

    在创建路由的实例对象时,开发者可以基于linkActiveClass属性,自定义类名

    const router = createRouter({
        history: createWebHashHistory(),
        linkActiveClass:'active-router',
        routes: [
            {
                path: '/home', component: MyHome
            },
            {
                path: '/',redirect:'/home' //访问根路径会重定向到home组件
            },
            {
                path: '/movie', component: MyMovie
            },
            {
                path: '/about', component: MyAbout
            },
    
        ]
    })
    
    嵌套路由

    通过路由来实现组件的嵌套展示

    步骤:

    • 声明子路由链接和子路由占位符
    
    
    • 在父路由规则中,通过children属性嵌套声明子路由规则
    const router = createRouter({
        history: createWebHashHistory(),
        routes: [
            {
                path: '/home', component: MyHome
            },
            {
                path: '/movie', component: MyMovie
            },
            {
                path: '/about', component: MyAbout,children:[
                    {
                    path:'tab1',component:Tab1
                },
                {
                    path:'tab2',component:Tab2
                },
            ]
            },
    
        ]
    })
    

    子路由规则的path不要以/开头

    在嵌套路由中实现路由的重定向

    const router = createRouter({
        history: createWebHashHistory(),
        routes: [
            {
                path: '/home', component: MyHome
            },
            {
                path: '/movie', component: MyMovie
            },
            {
                path: '/about',
                component: MyAbout,
                redirect:'/about/tab1',
                children:[
                    {
                    path:'tab1',component:Tab1
                },
                {
                    path:'tab2',component:Tab2
                },
            ]
            },
    
        ]
    })
    
    动态路由匹配

    指的是:把Hash地址中可变的部分定义为参数项,从而提高路由规则的复用性,在vue-router中使用英文冒号:来定义路由的参数

      {   
          path: '/movie/:id', component: MyMovie
       },
    

    获取动态路由参数值的方法:

    • $route.params参数对象
    
    
    • 使用props接受路由参数
    {
         path: '/movie/:id', component: MyMovie,
         props: true,
    },
    

    为了简化路由参数的获取形式,vue-router允许在路由规则开启props传参

    编程式导航

    通过调用API实现导航的方式,叫做编程式导航,与之对应的,通过点击链接实现导航的方式,叫做声明式导航

    • 普通网页中点击a链接,vue项目中点击都属于声明式导航
    • 平台网页中调用location.herf跳转到新页面的方式,属于编程式导航

    vue-router中编程式导航API

    • this.$router.push('hash地址') 跳转到指定Hash地址,并增加一条历史记录,从而展示对应的组件。
    • this.$router.replace('hash地址') 跳转到指定Hash地址,并替换当前的历史记录,从而展示对应的组件。
    • this.$router.go('数值n') 实现导航历史的前进、后退(-1),超过最大层数,则原地不动。

    $router.back() 后退到上一层页面

    $router.forward() 前进到下一层页面

    命名路由

    通过name属性为路由规则定义名称,叫做命名路由,name值不能重复,具有唯一性

    Hash地址特别长时体现出命名路由的优势

    • 使用命名路由实现声明式导航
    <template>
    	<h3>
            MyHome组件
        h3>
        <router-link :to="{name:'mov',params:{id : 3}}">goToMovierouter-link>
    template>
    
    <script>
    	export default {
            name:'MyHome',
        }
    script>
    
    • 使用命名路由实现编程式导航
    
    
    
    
    导航守卫

    导航守卫可以控制路由的访问权限

    image

    如何声明全局的导航守卫

    全局的导航守卫会拦截每个路由规则,从而对每个路由都进行访问权限的控制

    const router = createRouter({
       ...
    })
    //调用路由实例对象的beforeEach函数,fn必须是一个函数吗,每次拦截后,都会调用fn进行处理
    //声明全局的导航守卫,fn称为守卫方法
    router.beforeEach(fn)
        
    router.beforeEach(()=>{
        console.log('Ok')
    })
    
    

    守卫方法的三个形参(可选)

    router.beforeEach((to,from,mext)=>{
        console.log('Ok')
        //to 目标路由对象(信息)
        //from当前导航正要离开的路由对象
        //next 是一个函数,表示放行
    })
    

    注:

    在守卫方法中不声明next形参,则默认允许用户访问每一个路由

    在守卫方法中声明了next形参,则必须调用next()函数,否则不允许用户访问如何一个路由!

    next函数的3种调用方式

    //声明全局的导航守卫
    router.beforeEach((to, from, next) => {
        if (to.path === '/main') {
            //证明用户要访问后台主页  
            next(false)//强制用户停留在之前所处的组件
            next('login')//强制用户调转到指定页面
        } else {
            //证明用户要访问的不是后台主页 
            next()
        }
    })
    

    结合token控制后台主页的访问权限

    router.beforeEach((to, from, next) => {
        const tokenStr = localStorage.getItem('token') //读取token
    
    
        if (to.path === '/main' && !tokenStr) { //token不存在,需要登录
            //证明用户要访问后台主页  
           // next(false)//强制用户停留在之前所处的组件
            next('login')//强制用户调转到指定页面
        } else {
            //证明用户要访问的不是后台主页 
            next()
        }
    })
    
    

    Hash&History#

    路由器的两种工作模式:hash&history

    对于url来说:#及后面的内容就是hash值,hash值不会带给服务器。

    hash模式:

    1. 地址中永远带着#号,不美观;
    2. 若地址校验严格,会被标记为不合法;
    3. 兼容性较好;

    history模式:

    1. 地址干净,美观;
    2. 兼容性比hash模式较差;
    3. 应用部署上线需要后端支持,解决刷新页面服务端404问题;(node可以使用connect-history-api-fallback
  • 相关阅读:
    KingbaseES PL/SQL 过程语言参考手册(3. PL/SQL语言基础)
    记录一次存储过程新增测试数据
    【STM32】STM32学习笔记-修改主频 睡眠模式 停止模式 待机模式(45)
    DS18B20详解
    VSCode远程调试python
    DDR CTRL介绍
    Vue自定义指令
    python小记3
    H5页面内嵌到微信小程序和APP,做分享操作
    基于Android+OpenCV+CNN+Keras的智能手语数字实时翻译——深度学习算法应用(含Python、ipynb工程源码)+数据集(四)
  • 原文地址:https://www.cnblogs.com/gfhcg/p/17232523.html