Vue 3.0 路由

本文介绍了前端路由的概念和原理,详细讲解了Vue 3.0中vue-router的基本使用和高级用法,包括路由重定向、路由高亮、嵌套路由、动态路由匹配、编程式导航、命名路由以及导航守卫的实现和应用,旨在帮助开发者深入理解并掌握Vue 3.0的路由管理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、路由概念和原理

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

const express = require('express')
const router = express.Router()

router.get('/userlist',function(req,res){/*路由处理函数*/})
router.post('/adduser',function(req,res){/*路由处理函数*/})

module.exports = router

前端路由: 实现不同功能之间的切换,Hash 地址与组件之间的对应关系。

前端路由的工作方式

① 用户点击了页面上的路由链接

② 导致了 URL 地址栏中的 Hash 值发生了变化

③ 前端路由监听了到 Hash 地址的变化

④ 前端路由把当前 Hash 地址对应的组件渲染都浏览器中

实现简易的前端路由

1. 导入并注册 MyHome、MyMovie、MyAbout 三个组件

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

export default{
    components:{
        MyHome,
        MyMovie,
        MyAbout,
    }
}

2. 通过 <component> 标签的 is 属性,动态切换要显示的组件

<template>
    <h1>App 组件</h1>
    <component :is="comName"></component>
</template>

export default{
    data() {
        return {
            comName: 'my-home', //要展示的组件的名称
        }
    }
}

3. 在组件的结构中声明如下 3 个 <a> 链接,通过点击不同的 <a> 链接,切换浏览器地址栏中的 Hash 值。

<a href="#/home">Home</a>
<a href="#/movie">Movie</a>
<a href="#/about">About</a>

4. 在 created 生命周期函数中监听浏览器地址栏中 Hash 地址的变化,动态切换要展示的组件的名称

created(){
    window.onhashchange = () => {
        switch(location.hash) {
            case: '#/home':
                this.comName = 'my-home'
                break
            case: '#/movie':
                this.comName = 'my-movie'
                break
            case: '#/about':
                this.comName = 'my-about'
                break
        }
    }
}

二、vue-router 的基本使用

在项目中安装 vue-router(vue3 的项目中只能用 vue-router 4.x)

npm install vue-router@next -S

定义路由组件

<template>
    <h3>组件</h3>
</template>

<script>
    export default{
       name:'MyAbout',
    }
</script>

<style>
</style>

声明路由链接<router-link> 和占位符<router-view> 

<template>
    <h1>组件</h1>
    <!--声明路由链接-->
    <router-link to="/home">首页</router-link>&nbsp;
    <router-link to="/movie">首页</router-link>&nbsp;
    <router-link to="/about">首页</router-link>
    <!--声明路由占位符-->
    <router-view></router-view>
</template>

创建路由模块

  • 从 vue-router 中按需导入两个方法
  • 导入需要使用路由控制的组件
  • 创建路由实例对象
  • 向外共享路由实例对象
  • 在 main.js 中导入并挂载路由模块

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

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

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

import Home from './components/MyHome.vue'
import Movie from './components/MyMovie.vue'
import About from './components/MyAbout.vue'

创建路由实例对象

const router = createRouter({
    history: createWebHashHistory(),
    routes:[
       { path: '/home',component:Home },
       { path: '/movie',component:Movie },
       { path: '/about',component:About },
    ],
})

向外共享路由实例对象

export default router

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

import { createApp } from 'vue'
import App from './App.vue'
import './index.css'

import router from './router'

const app = createApp(App)

app.use(router)
app.mount('#app')

三、vue-router 的高级用法

1. 路由重定向

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

通过路由规则的 redirect 属性,指定一个新的路由地址,可以很方便地设置路由的重定向:

const router = createRouter({
    history:createWebHashHistory(),
    routes:[
        { path:'/', redirect: '/home' },
        { path: '/home', component: Home },
        { path: '/movie', component: Movie },
        { path: '/about', component: About },
    ]
})

2. 路由高亮

默认的高亮 class 类

被激活的路由链接,默认会应用一个叫做 router-link-active 的类名:

.router-link-active{
    background-color:red;
    color:white;
    font-weight:bold;
}

自定义路由高亮的 class 类

 linkActiveClass 属性,自定义路由链接被激活时所应用的类名:

const router = createRouter({
    history:createWebHashHistory(),
    linkActiveClass: 'router-active',
    routes:[
        { path:'/', redirect: '/home' },
        { path: '/home', component: Home },
        { path: '/movie', component: Movie },
        { path: '/about', component: About },
    ]
})

3. 嵌套路由

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

  • 声明子路由链接和子路由占位符
<template>
    <h1>MyAbout组件</h1>
    <!--声明子路由链接-->
    <router-link to="/about/tab1">首页</router-link>&nbsp;
    <router-link to="/about/tab2">首页</router-link>&nbsp;
    <!--声明子路由占位符-->
    <router-view></router-view>
</template>
  • 通过 children 属性声明子路由规则

在 router.js 路由模块中,导入需要的组件,并使用 children 属性声明子路由规则。

注意:声明子路由时不要加/

import Tab1 from './components/tabs/MyTab1.vue'
import Tab2 from './components/tabs/MyTab2.vue'
const router = createRouter({
    routes:[
        { 
            path: '/about', 
            component: About,
            redirect: './about/tab1',    //重定向
            children:[
              { path: 'tab1', component:Tab1 },
              { path: 'tab2', component:Tab2 },
            ] 
        },
    ]
})

4. 动态路由匹配

把 Hash 地址中可变的部分定义为参数项,从而提高路由规则的复用性。在 vue-router 中

使用英文的冒号(:)来定义路由的参数项。

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

可以使用 $route.params 对象访问到动态匹配的参数值。

<template>
    <h3>MyMovie组件 --- {{$router.params.id}}</h3>
</template>

<script>
    export default{
        name: 'MyMovie',
    }
</script>

使用 props 接收路由参数

//可在Movie组件中,以props的形式接收到路由规则匹配的参数项
{ path:'/movie/:id',component:Movie, props:true}
<template>
    <h3>MyMovie组件 --- {{id}}</h3>
</template>

<script>
    export default{
        props:['id'],
    }
</script>

5. 编程式导航

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

  • 普通网页中点击 <a> 链接、vue 项目中点击 <router-link> 都属于声明式导航
  • 普通网页中调用 location.href 跳转到新页面的方式,属于编程式导航

this.$router.push('hash 地址'): 跳转到指定 Hash 地址,从而展示对应的组件

<template>
    <h3>MyHome</h3>
    <button @click="gotoMovie(3)">go to Movie</button>
</template>

<script>
export default{
    methods:{
        gotoMovie(id){
            this.$router.push('/movie/${id}')
        },
    },
}
</script>

this.$router.go(数值 n): 实现导航历史的前进、后退

<template>
    <h3>MyMovie</h3>
    <button @click="goBack">后退</button>
</template>

<script>
export default{
    props:['id'],
    methods:{
        goBack(){ this.$router.go(-1)}
    },
}
</script>

6. 命名路由

命名路由的 name 值不能重复,必须保证唯一性!

命名路由实现声明式导航

<template>
    <h3>MyHome</h3>
    <router-link :to="{ name:'mov', params:{id : 3}}">go to Movie</router-link>
</template>

<script>
export default{
    name:'MyHome',
}
</script>

命名路由实现编程式导航

<template>
    <h3>MyHome</h3>
    <button @click="gotoMovie(3)">go to Movie</button>
</template>

<script>
export default{
    methods: {
        gotoMovie(id){
            this.$router.push({name:'mov',params:{id : 3}})
        },
    },
}
</script>

7. 导航守卫

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

const router = createRouter({...})
//每次拦截到路由的请求都会用fn处理
router.beforeEach(fn)

全局导航守卫的守卫方法中接收 3 个形参

const router = createRouter({...})
router.beforeEach((to, from, next)=>{
    //to目标路由对象
    //from当前导航要离开时的路由对象
    //next表示放行
})
  • 守卫方法中如果不声明 next 形参,则默认允许用户访问每一个路由
  • 守卫方法中如果声明了 next 形参,则必须调用 next() 函数,否则不允许用户访问任何一个路由

next函数的3种调用方式

  • 直接放行:next()
  • 强制其停留在当前页面:next(false)
  • 强制其跳转到登录页面:next('/login')

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

router.beforeEach((to, from, next)=>{
    const token = localStorage.getItem('token') //读取token
    if(to.path === './main' && !token){    //想要访问主页且token不存在
        //next(false)    //不允许跳转
        next('/login')    //强制跳到登陆界面
    }else{
        next()    //允许放行
    }
})

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值