【Vue】VueRouter路由

系列文章目录

第七章 VueRouter路由


文章目录


第一节:VueRouter基础

在网页中,经常需要发生页面更新或者跳转。这时候我们就可以使用Vue-Router来帮我们实现。Vue-Router是用来做路由的,也就是定义url规则与具体的View映射的关系。可以在一个单页面中实现数据的更新。

一、安装:

通过命令:npm install vue-router@4.3.0 --save ,或者在创建项目的时候,选择添加Vue-Router的支持。

二、基本使用:

1. 创建路由代码:Single Page Application:SPA

在src/router/index.js中,填入以下代码:

js 复制代码
import { createRouter, createWebHistory } from 'vue-router'
import HomeView from '../views/HomeView.vue'

const router = createRouter({
  history: createWebHistory(import.meta.env.BASE_URL),
  routes: [
    {
      path: '/',
      name: 'home',
      component: HomeView
    },
    {
      path: '/about',
      name: 'about',
      component: () => import('../views/AboutView.vue')
    }
  ]
})

export default router

以上代码解释如下:

  1. 使用createRouter创建路由对象。
  2. 路由工作模式,有两种工作模式:
  • history模式:路由中不包含#,更加美观,但是在后期部署后,如果前端项目代码和后端项目代码部署在同一个域名下,则容易产生路由混淆(前端路由和后端路由混淆在一起了)。以上代码用的是history模式,代码为:
js 复制代码
const router = createRouter({
    history:createWebHistory(), //history模式
})
  • hash模式:路由中包含#,不太美观,对SEO优化不够友好。好处是兼容性更好,即使前端代码和后端代码部署在同一个域名下,也不会产生路由混淆。使用hash模式的代码为:
js 复制代码
const router = createRouter({
    history:createWebHashHistory(), //hash模式
})
  1. routes是一个数组,里面是对象数据,每个对象中的属性作用分别如下:
  • path:该路由对应的path。
  • component:组件对象,既可以先导入,也可以指定组件的时候使用import语句来导入。
  • name:路由名称,后期在做路由反转的时候可以使用。

2. 使用路由

然后在main.js文件中对router进行使用:

js 复制代码
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'

const app = createApp(App)

app.use(router)

app.mount('#app')

以上相关代码解释如下:

从src/router/index.js中导入router对象。

执行app.use(router)代码,即可使用此路由了。

3. 展示路由:

在App.vue中的代码如下:

html 复制代码
<script setup>
import { RouterLink, RouterView } from 'vue-router'
</script>

<template>
  <header>
    <div class="wrapper">
      <nav>
        <RouterLink to="/">Home</RouterLink>
        <RouterLink to="/about">About</RouterLink>
      </nav>
    </div>
  </header>

  <RouterView />
</template>

以上相关代码解释如下:

在模板中,使用RouterLink定义路由链接,此组件有点类似html中的a标签,在点击后会跳转到to属性指定的路由上去。to除了直接写path外,还可以通过name来定义,比如:

html 复制代码
<RouterLink :to="{name: 'home'}">Home</RouterLink>

使用RouterView标识路由出口,在进入路由A后,路由A所对应的组件会显示在RouterView的地方。

二、嵌套路由

在某个页面中,如果还需要通过路由更新局部模块,那么可以通过嵌套路由来实现,只要配置children就可以了。

  1. src/router/index.js代码如下:
js 复制代码
const router = createRouter({
  history: createWebHistory(import.meta.env.BASE_URL),
  routes: [
    {
      path: '/',
      name: 'home',
      component: HomeView
    },{
      path: '/news',
      component: () => import('../views/news/NewsView.vue'),
      name: 'news',
      children: [{
        path: 'detail', 
        name: 'news-detail', 
        component: import('../views/news/NewsDetailView.vue')
      }]
    },
    {
      path: '/about',
      name: 'about',
      component: () => import('../views/AboutView.vue')
    }
  ]
})
  1. src/views/news/NewsView.vue代码如下:
html 复制代码
<template>
<ul>
    <li><RouterLink :to="{name: 'news-detail'}">新闻1</RouterLink></li>
    <li>新闻2</li>
    <li>新闻3</li>
</ul>
<RouterView></RouterView>
</template>
  1. src/views/news/NewsDetailView.vue代码如下:
html 复制代码
<template>
<h1>AIGC将迎来爆发式增长!</h1>
</template>

三、路由传参

路由传参有两种方式,一种是在定义路由的时候指定参数,另一种是通过查询字符串的方式传参。

1. 路由指定参数

src/router/index.js代码如下:

js 复制代码
const router = createRouter({
  history: createWebHistory(import.meta.env.BASE_URL),
  routes: [
    path: '/news',
    component: () => import('../views/news/NewsView.vue'),
    name: 'news',
    children: [{
      path: 'detail/:pk',
      name: 'news-detail',
      component: import('../views/news/NewsDetailView.vue')
    }]
    }
  ]
})

在使用这个路由的时候,其代码如下:

html 复制代码
<RouterLink :to="{name: 'news-detail', params: {pk: 1}}">新闻1</RouterLink>

以后在NewsDetailView.vue的onMounted生命周期函数中可以通过以下方式获取到参数:

js 复制代码
<script setup name="NewsDetailView">
  import { onMounted } from 'vue';
  import { useRoute } from 'vue-router';

  const route = useRoute();

  onMounted(() => {
    const pk = route.params.pk;
    console.log(pk);
  })
</script>

2. 查询字符串传参

使用查询字符串传参,不需要预先在路由定义的时候指定参数,使用的时候直接传递即可,示例代码如下:/news/detail?pk=1&page=2

html 复制代码
<RouterLink :to="{name: 'news', query: {page: 1}}">News</RouterLink>

以后在NewsView.vue组件中的onMounted生命周期函数中通过以下代码即可获取到:

四、编程式导航

之前我们学习了使用可以在用户点击的情况下进行页面更新。但有时候我们想要在js中手动的修改页面的跳转,这时候就需要使用编程式导航了。

1. router.push跳转:

想要导航到不同的URL,则使用router.push方法。这个方法会向history栈添加一个新的记录,所以,当用户点击浏览器后退按钮时,则回到之前的URL。

当你点击时,这个方法会在内部调用,所以说,点击等同于调用router.push(...)。

示例代码如下:

html 复制代码
<script setup>
  import {useRouter} from "vue-router";

  const router = useRouter();

  // 字符串路径
  router.push('/users/eduardo')

  // 带有路径的对象
  router.push({ path: '/users/eduardo' })

  // 命名的路由,并加上参数,让路由建立 url
  router.push({ name: 'user', params: { username: 'eduardo' } })

  // 带查询参数,结果是 /register?plan=private
  router.push({ path: '/register', query: { plan: 'private' } })

  // 带 hash,结果是 /about#team
  router.push({ path: '/about', hash: '#team' })
</script>

注意:如果提供了 path,params 会被忽略,上述例子中的 query 并不属于这种情况。取而代之的是下面例子的做法,你需要提供路由的 name 或手写完整的带有参数的 path :

js 复制代码
const username = 'eduardo'
// 我们可以手动建立 url,但我们必须自己处理编码
router.push(`/user/${username}`) // -> /user/eduardo
// 同样
router.push({ path: `/user/${username}` }) // -> /user/eduardo
// 如果可能的话,使用 `name` 和 `params` 从自动 URL 编码中获益
router.push({ name: 'user', params: { username } }) // -> /user/eduardo
// `params` 不能与 `path` 一起使用
router.push({ path: '/user', params: { username } }) // -> /user

2. router.replace替换

它的作用类似于 router.push,唯一不同的是,它在导航时不会向 history 添加新记录,正如它的名字所暗示的那样------它取代了当前的条目。

也可以直接在传递给 router.push 的 to 参数中增加一个属性 replace: true :

js 复制代码
router.push({ path: '/home', replace: true })
// 相当于
router.replace({ path: '/home' })

第二节:VueRouter进阶

一、导航守卫

导航守卫分为:全局守卫、组件导航守卫以及路由导航守卫。下面分别来进行讲解。

1. 全局守卫:

全局守卫有beforeEach 和afterEach ,即在跳转前和跳转后的导航守卫。

首先看下beforeEach,示例代码如下:

js 复制代码
router.beforeEach((to, from) => {
  if (
    // 检查用户是否已登录
    !isAuthenticated &&
    // ❗️ 避免无限重定向
    to.name !== 'Login'
  ) {
    // 将用户重定向到登录页面
    return { name: 'Login' }
  }
})

如果beforeEach的回调函数中返回的是true或者什么都没返回,则跳转到默认的路由,否则跳转到返回的路由。

afterEach导航路由为已经改变完成后的守卫。示例代码如下:

js 复制代码
router.afterEach(function(to,from){
  console.log('to:',to);
  console.log('from:',from);
})

2. 组件内导航守卫:

组件内导航守卫只能使用以下两个方法:

onBeforeRouteLeave:在离开当前路由前调用。如果返回false,将会取消路由离开。比如:

js 复制代码
router.afterEach(function(to,from){
  console.log('to:',to);
  console.log('from:',from);
})

onBeforeRouteUpdate:在路由发生更新时调用,比如从/user/1更新到/user/2,就会执行该守卫方法。一般这个方法用的比较少。

3. 路由导航守卫:

在定义路由的时候,可以指定beforeEnter导航守卫,示例代码如下:

js 复制代码
const routes = [
  {
    path: '/users/:id',
    component: UserDetails,
    beforeEnter: (to, from) => {
      // reject the navigation
      return false
    },
  },
]

二、路由元信息

有时,你可能希望将任意信息附加到路由上,如过渡名称、谁可以访问路由等。这些事情可以通过接收属性对象的meta属性来实现,并且它可以在路由地址和导航守卫上都被访问到。定义路由的时候你可以这样配置 meta 字段:

js 复制代码
const routes = [
  {
    path: '/posts',
    component: PostsLayout,
    children: [
      {
        path: 'new',
        component: PostsNew,
        // 只有经过身份验证的用户才能创建帖子
        meta: { requiresAuth: true },
      },
      {
        path: ':id',
        component: PostsDetail
        // 任何人都可以阅读文章
        meta: { requiresAuth: false },
      }
    ]
  }
]

那么以后可以通过路由.meta 访问到元数据。示例代码如下:

js 复制代码
router.beforeEach((to, from) => {
  // 而不是去检查每条路由记录
  // to.matched.some(record => record.meta.requiresAuth)
  if (to.meta.requiresAuth && !auth.isLoggedIn()) {
    // 此路由需要授权,请检查是否已登录
    // 如果没有,则重定向到登录页面
    return {
      path: '/login',
      // 保存我们所在的位置,以便以后再来
      query: { redirect: to.fullPath },
    }
  }
})
相关推荐
用户841794814567 分钟前
vxe-gantt table 甘特图如何设置任务视图每一行的背景色
vue.js
前端老宋Running8 分钟前
一次从“卡顿地狱”到“丝般顺滑”的 React 搜索优化实战
前端·react.js·掘金日报
隔壁的大叔8 分钟前
如何自己构建一个Markdown增量渲染器
前端·javascript
用户44455436542610 分钟前
Android的自定义View
前端
WILLF11 分钟前
HTML iframe 标签
前端·javascript
枫,为落叶28 分钟前
Axios使用教程(一)
前端
小章鱼学前端33 分钟前
2025 年最新 Fabric.js 实战:一个完整可上线的图片选区标注组件(含全部源码).
前端·vue.js
ohyeah35 分钟前
JavaScript 词法作用域、作用域链与闭包:从代码看机制
前端·javascript
流星稍逝36 分钟前
手搓一个简简单单进度条
前端
uup41 分钟前
JavaScript 中 this 指向问题
javascript