【Vue工程】005-Vue Router

【Vue工程】005-Vue Router

文章目录

  • 【Vue工程】005-Vue Router
  • 一、概述
    • 1、Slogan
    • 2、官网
    • 3、参考文章
  • 二、安装
  • 三、基本使用
    • 1、定义路由
    • 2、创建路由实例
    • 3、在 `main.ts` 注册路由
    • 4、在 `App.vue` 定义路由出口
  • 四、嵌套路由
    • 1、修改路由
    • 2、定义嵌套路由出口
  • 五、配置404页面
  • 六、声明式、编程式导航
    • 1、声明式导航(在模板中进行路由跳转)
    • 2、编程式导航(组合式API)
  • 七、重定向
  • 八、路由跳转传参
    • 1、动态路由匹配
      • 路由配置
      • 当前组件:传参
      • 跳转目标组件:接收参数
      • 运行结果
      • 路由嵌套刷新页面策略
    • 2、查询参数
      • 路由配置
      • 当前组件:传参
      • 跳转目标组件:接收参数
      • 运行结果
  • 九、导航守卫
    • 1、全局前置守卫
    • 2、路由独享守卫
    • 3、组件内守卫
  • 十、路由元信息
  • 十一、router-link
  • 十二、动态路由
    • 1、修改 `router/routes.ts`
    • 2、修改 `pages/login.vue`
    • 3、修改 `App.vue`

一、概述

1、Slogan

为 Vue.js 提供富有表现力、可配置的、方便的路由。

2、官网

https://router.vuejs.org/zh/

3、参考文章

人家写得太好,没多少可改的,部分内容直接摘录。

https://juejin.cn/post/7223779544368627773

二、安装

pnpm add vue-router

三、基本使用

1、定义路由

创建文件 src/router/routes.ts

const routes = [
  {
    path: '/',
    component: () => import('@/pages/login.vue'),
  },
  {
    path: '/home',
    component: () => import('@/pages/home.vue'),
  },
];

export default routes;

src/pages/login.vue






src/pages/home.vue

<template>
  <div>home</div>
</template>

<script lang="ts" setup></script>

<style scoped></style>

2、创建路由实例

创建文件 src/router/index.ts

import { createRouter, createWebHistory } from 'vue-router';
import routes from './routes';

const router = createRouter({
  history: createWebHistory(),
  routes,
});

export default router;

3、在 main.ts 注册路由

import { createApp } from 'vue';
import './style.css';
import App from './App.vue';
// 导入路由
import router from './router';

const app = createApp(App);

// 注册路由
app.use(router);

app.mount('#app');

4、在 App.vue 定义路由出口

<template>
  <!--  写法一-->
  <!--  <router-view v-slot="{ Component }">-->
  <!--    <transition name="fade" mode="out-in">-->
  <!--      <component :is="Component" />-->
  <!--    </transition>-->
  <!--  </router-view>-->
  <!--  写法二-->
  <router-view />
</template>

<style></style>

四、嵌套路由

在 App.vue 中定义的 router-view,这是顶层的出口,渲染最高级路由匹配到的组件。

如果要实现登录之后左侧菜单栏不变,右侧随路由的切换变化显示的内容,需使用嵌套路由。

1、修改路由

修改文件 src/router/routes.ts

其他 vue 文件此处省略。

const routes = [
  {
    path: "/login",
    component: () => import("@/pages/login.vue"),
  },
  {
    path: "/home",
    component: () => import("@/pages/home.vue"),
    children: [
      {
        path: "/home/user",
        component: () => import("@/pages/user.vue"),
      },
      {
        path: "/home/manage",
        component: () => import("@/pages/manage.vue"),
      },
    ],
  },
];

export default routes;

2、定义嵌套路由出口

修改 src/pages/home.vue

<template>
  <div>
    菜单栏
    <router-view />
  </div>
</template>

五、配置404页面

修改router/routes.ts

const routes = [
  {
    path: '/',
    component: () => import('@/pages/login.vue'),
  },
  {
    path: '/home',
    component: () => import('@/pages/home.vue'),
  },
  {
    path: '/:pathMatch(.*)*',
    component: () => import('@/pages/notFound.vue'),
  },
];

export default routes;

六、声明式、编程式导航

1、声明式导航(在模板中进行路由跳转)

 跳转home ;

2、编程式导航(组合式API)

<script setup lang="ts">
import { useRouter } from 'vue-router';

const router = useRouter();

const handleManage = () => {
  router.push('/home/manage');
};
</script>

七、重定向

场景:在嵌套路由中,当访问 / 时想重定向到/home

修改router/routes.ts

{
    path: '/home',
    component: () => import('@/pages/home.vue'),
    redirect: '/home/user', // 新增
    children: [
      {
        path: '/home/user',
        component: () => import('@/pages/user.vue'),
      },
      {
        path: '/home/manage',
        component: () => import('@/pages/manage.vue'),
      },
    ],
},

八、路由跳转传参

我的另一篇文章:https://blog.csdn.net/qq_29689343/article/details/130172191

1、动态路由匹配

路由配置

const routes: RouteRecordRaw[] = [
  {
    path: '/',
    name: 'Hello',
    component: Hello,
  },
  {
      path: '/next-page/:message',
      name: 'NextPage',
      component: NextPage,
  },
];

当前组件:传参

<template>
  <button @click="toNextPage">toNextPage</button>
</template>

<script setup lang="ts">
import {useRouter} from 'vue-router';
// 得到 router 对象
const router = useRouter();
// 页面跳转
const toNextPage = () => {
  router.push({name: 'NextPage', params: {message: "基本字符串"}});
}
</script>

跳转目标组件:接收参数

<template>
  <h1>NextPage</h1>
  <h1>基本数据:{{ route.params.message }}</h1>
</template>

<script setup lang="ts">
import { useRoute } from "vue-router";
import {onMounted} from "vue";
const route = useRoute();
</script>

运行结果

【Vue工程】005-Vue Router_第1张图片

路由嵌套刷新页面策略

<template>
  <h1>NextPage</h1>
  <h1 :key="thisVersion">基本数据:{{ route.params.message }}</h1>
</template>

<script setup lang="ts">
import { useRoute } from "vue-router";
import {ref, watch} from "vue";
const route = useRoute();
// 当前版本
const thisVersion = ref(0);
// 监听参数变化,更新版本,刷新组件(大致写法,未测试)
watch(() => route.params.message, () => {
  thisVersion.value ++;
})
</script>

2、查询参数

路由配置

const routes: RouteRecordRaw[] = [
  {
    path: '/',
    name: 'Hello',
    component: Hello,
  },
  {
      path: '/next-page',
      name: 'NextPage',
      component: NextPage,
  },
];

当前组件:传参

<template>
  <button @click="toNextPage">toNextPage</button>
</template>

<script setup lang="ts">
import {useRouter} from 'vue-router';
// 得到 router 对象
const router = useRouter();
// 页面跳转
const toNextPage = () => {
  router.push({name: 'NextPage', query: {message: "基本字符串", name: "訾博"}});
}
</script>

跳转目标组件:接收参数

<template>
  <h1>NextPage</h1>
  <h1>基本数据:{{ route.query.message }}</h1>
  <h1>基本数据:{{ route.query.name }}</h1>
</template>

<script setup lang="ts">
import { useRoute } from "vue-router";
const route = useRoute();
</script>

运行结果

【Vue工程】005-Vue Router_第2张图片

九、导航守卫

1、全局前置守卫

使用场景:做登录判断,未登陆用户跳转到登录页

修改router/index.ts

import { createRouter, createWebHistory } from 'vue-router';
import routes from './routes';

const router = createRouter({
  history: createWebHistory(),
  routes,
});

router.beforeEach((to, from) => {
  if (to.path === '/login') {
    // 在登录页做清除操作,如清除token等
  }

  if (!localStorage.getItem('token') && to.path !== '/login') {
    // 未登陆且访问的不是登录页,重定向到登录页面
    return '/login';
  }
});

export default router;

2、路由独享守卫

使用场景:部分页面不需要登录,部分页面需要登录才能访问

修改 router/routes.ts

// 权限校验
const auth = () => {
  if (!localStorage.getItem('token')) {
    // 未登陆,重定向到登录页面
    return '/login';
  }
};

// 路由配置
const routes = [
  {
    path: '/',
    component: () => import('@/pages/login.vue'),
  },
  {
    path: '/home',
    component: () => import('@/pages/home.vue'),
    beforeEnter: auth,
  },
];

export default routes;

3、组件内守卫

使用场景:预防用户在还未保存修改前突然离开。该导航可以通过返回 false 来取消

<script setup lang="ts">
import { onBeforeRouteLeave } from 'vue-router';

// 与 beforeRouteLeave 相同,无法访问 `this`
onBeforeRouteLeave((to, from) => {
  const answer = window.confirm('确定离开吗');
  // 不再跳转
  if (!answer) return false;
});
</script>

十、路由元信息

将自定义信息附加到路由上,例如页面标题,是否需要权限,是否开启页面缓存等

使用情景:使用路由元信息+全局前置守卫实现部分页面不需要登录,部分页面需要登录才能访问

修改router/routes.ts

const routes = [
  {
    path: "/home",
    component: () => import("@/pages/home.vue"),
    redirect: "/home/user",
    children: [
      {
        path: "/home/user",
        component: () => import("@/pages/user.vue"),
      },
      {
        path: "/home/manage",
        component: () => import("@/pages/manage.vue"),
        meta: {
          title: "管理页", // 页面标题
          auth: true, // 需要登录权限
        },
      },
    ],
  },
];

修改 router/index.ts

router.beforeEach((to, from) => {
  if (!localStorage.getItem("token") && to.meta.auth) {
    // 此路由需要授权,请检查是否已登录
    // 如果没有,则重定向到登录页面
    return {
      path: "/login",
      // 保存我们所在的位置,以便以后再来 (因为跳转到登录页面,用户登录之后还需跳转回来)
      query: { redirect: to.fullPath },
    };
  }
});

十一、router-link

router-link 组件默认为a标签,在vue router 3.x中,可通过tag属性更改标签名,event属性更改事件名

在vue router 4.x中,这两个属性已被删除,通过作用域插槽(子组件给父组件传值的插槽)实现自定义导航标签

示例:将导航标签改为div,且需双击触发

<router-link v-slot="{ href, navigate, isExactActive }" to="/home/user" custom>
  <div :class="{ active: isExactActive }" :href="href" @dblclick="navigate">跳转user</div>
</router-link>

十二、动态路由

与动态路由匹配不同,动态路由是手动添加路由表中没有的路由,通常用在权限校验中,如果没有该权限,直接访问该路由失败

1、修改 router/routes.ts

const routes = [
  {
    path: "/login",
    component: () => import("@/pages/login.vue"),
  },
  {
    path: "/register/:plan",
    component: () => import("@/pages/register.vue"),
  },
  {
    path: "/home",
    name: "Home", // 增加 name,动态路由通过 name 挂载到该子路由下
    component: () => import("@/pages/home.vue"),
    redirect: "/home/user",
    children: [
      {
        path: "/home/user",
        component: () => import("@/pages/user.vue"),
      },
    ],
  },
  {
    path: "/:pathMatch(.*)*",
    component: () => import("@/pages/notFound.vue"),
  },
];

// 将 /home/manage 拆出来
export const manageRoute = {
  path: "/home/manage",
  component: () => import("@/pages/manage.vue"),
};

export default routes;

2、修改 pages/login.vue

<script setup lang="ts">
  localStorage.setItem('role', 'admin'); //在登录页存储用户等级
</script>;

3、修改 App.vue

如果 localStorage.getItem(‘role’) 的值不为 admin ,直接访问 /home/manage,会返回 404 页面

<script setup lang="ts">
import { watch } from 'vue';
import { useRouter, useRoute } from 'vue-router';
import { manageRoute } from '@/router/routes';

const router = useRouter();
const route = useRoute();
watch(route, async (newVal) => {
  const role = localStorage.getItem('role');
  if (role && role === 'admin') {
    // admin 直接访问
    router.addRoute('Home', manageRoute);
    // 防止页面刷新,路由丢失
    if (newVal.fullPath === '/home/manage') {
      // 会返回404页面
      await router.replace('/home/manage');
    }
  }
});
</script>

你可能感兴趣的:(Vue.js,vue.js,javascript,前端)