jck28 - 小柒 - 前端开发 - Vue 路由管理

一,vue 路由管理

1.1 单页面应用介绍

image
image

1.2 vue Router安装

image

  • 如果是新创建项目,直接在创建项目时选择引入vue-router
    image

  • 已创建的项目,可以使用命令安装

    • 安装命令:npm install vue-router@4
    • 查看命令:npm list
      image

1.3 vue 路由模式

image

1.4 路由定义和使用

image
image

1.5 代码实例

  • 新建子组件 Ceshiren.vue和Hogwarts.vue
<template>
  <div>
    <h1>Ceshiren</h1>
    <p>Ceshiren内容</p>
    <h3>Ceshiren页脚</h3>
  </div>
</template>
<template>
  <div>
    <h1>Hogwarts</h1>
    <p>Hogwarts内容</p>
    <h3>Hogwarts页脚</h3>
  </div>
</template>
  • 新建router文件夹,再新建一个index.js的文件,创建路由
import { createRouter, createWebHashHistory } from "vue-router"
import Ceshiren from "../views/Ceshiren.vue"
import Hogwarts from "../views/Hogwarts.vue"

// 创建路由关系表
const routers=[
    {
        path: "/ceshiren",
        component: Ceshiren
    },
    {
        path: "/hogwarts",
        component:  Hogwarts  
    }
]

// 创建路由对象
const router = createRouter({
    history: createWebHashHistory(),
    routes: routers
})

// 暴露路由
export default router
  • 在main.js文件添加使用路由
// import './assets/main.css'

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

import router from './router'

// 使用路由
createApp(App).use(router).mount('#app')

// createApp(App).mount('#app')

  • 根组件App.vue
// <script setup>
//     import DynamicFC from "./views/DynamicFC.vue"
// </script>

<template>
   <div class="nav">
      <router-link to="/ceshiren">测试人页面</router-link>
      <br>
      <br>
      <router-link to="/hogwarts">霍格沃兹页面</router-link>
      <router-view></router-view>
   </div>
</template>

<style scoped>
    .nav{
        font-size:30px;
       margin-left: 20px;
    }
</style>

二,带参数的动态路由匹配

2.1 简介

image
image
image
image

2.2 代码示例

  • index.js
import { createRouter, createWebHashHistory } from "vue-router"
import Ceshiren from "../views/Ceshiren.vue"
import Hogwarts from "../views/Hogwarts.vue"
import NotFound from "../views/NotFound.vue"

// 创建路由关系表
const routers=[
    {
        path: "/",
        component: Ceshiren
    },
    {
        path: "/ceshiren",
        component: Ceshiren
    },
    {
        path: "/hogwarts/:id(\\d+)/:name([a-z]+)",
        component:  Hogwarts  
    }
    ,
    {
        path: "/:pathMatch(.*)*",
        component:  NotFound  
    }
]

// 创建路由对象
const router = createRouter({
    history: createWebHashHistory(),
    routes: routers
})

// 暴露路由
export default router
  • 根组件App.vue
// <script setup>
//     import DynamicFC from "./views/DynamicFC.vue"
// </script>

<template>
   <div class="nav">
      <router-link to="/ceshiren" class="box">测试人页面</router-link>
      
      <router-link to="/hogwarts/11/demi" class="box">霍格沃兹页面demi</router-link>
      <router-link to="/hogwarts/21/sammy" class="box">霍格沃兹页面sammy</router-link>
      <router-link to="/hogwarts/231/alex" class="box">霍格沃兹页面alex</router-link>
      <router-view></router-view>
   </div>
</template>

<style scoped>
    .box{
      font-size:25px;
      margin-left: 40px;
    }
</style>

三,嵌套路由

3.1 简介

image
image
image
image

3.2 代码示例

  • nestChild.vue
<template>
    <h1>NestChild</h1>
    <p>这是子页面的内容</p>
    <p>这是子页面的内容</p>
    <p>ID: {{this.$route.params.id}}</p>
    <p>name: {{this.$route.params.name}}</p>
</template>
  • nestChild.vue
<template>
    <div>
        <h2>这是父页面的标题</h2>
        <router-link to="/user/child" class="box">通过URL进入子页面</router-link>
        <!-- 子路由页面带参数的情况 -->
        <router-link :to="{name:'nestChild',params:{id:12, name:'tommy'}}" class="box">通过name进入子页面</router-link>
        <router-view></router-view>
    </div>
</template>

<style scoped>
    .box{
      font-size:20px;
      margin-right: 40px;
    }
</style>
  • index.js路由关系列表添加
{
        path: "/user",
        // 命名路由
        name:"nestUser",
        component:  User, 
        children:[{
            // 子路由带动态参数的情况
            path: "child/:id/:name",
            name:"nestChild",
            component:  Child  
        }]
    }
  • 根组件App.vue
// <script setup>
//     import DynamicFC from "./views/DynamicFC.vue"
// </script>

<template>
   <div class="nav">
      <p>
         <router-link to="/ceshiren" class="box">测试人页面</router-link>
         <router-link to="/hogwarts/11/demi" class="box">霍格沃兹页面demi</router-link>
         <router-link to="/hogwarts/21/sammy" class="box">霍格沃兹页面sammy</router-link>
         <router-link to="/hogwarts/231/alex" class="box">霍格沃兹页面alex</router-link>
      </p>
      <p>
         <router-link to="/user" class="box">通过URL进入user页面</router-link>
         <router-link :to="{name:'nestUser'}"  class="box">通过name进入user页面</router-link>
      </p>
      <div>
         <router-view></router-view>
      </div>
   </div>
</template>

<style scoped>
    .box{
      font-size:25px;
      margin-right: 40px;
    }
</style>

四,重定向和别名

4.1 简介

image
image
image
image

4.2 重定向代码示例

  • 新建一个子组件Redirect.vue
<template>
    <div>
        <h1>Redirect Page</h1>
    </div>
</template>
  • 在index.js文件的路由关系表添加路由路径
   {
        path: "/macbookPro",
        // 通过路径重定向
        // redirect:{path: "/redirectPage"}
        // 通过名字重定向
        redirect: {name:"rp"}
    },
    {
        path: "/redirectPage",
        name:"rp",
        component:  Redirect  
    }
  • 根组件App.vue
      <p>
         <router-link to="/macbookPro" class="box">macbookPro重定向页面</router-link>
      </p>

4.3 别名代码示例

  • 新建一个子组件Alias.vue
<template>
    <div>
        <h1>Alias Page</h1>
    </div>
</template>
  • 在index.js文件的路由关系表添加路由路径
   {
        path: "/aliaspage",
        // 单个别名
        // alias:"/aliasName",
        // 多个别名
        alias:["/alias1", "/alias2", "/alias3"],
        component:  Alias  
    }
  • 根组件App.vue
      <p>
         <router-link to="/aliasName" class="box">AliasName</router-link>
         <router-link to="/alias1" class="box">Alias1</router-link>
         <router-link to="/alias2" class="box">Alias2</router-link>
         <router-link to="/alias3" class="box">Alias3</router-link>
      </p>

五,编程式导航

5.1 简介

image
image
image
image

5.2 代码示例

  • 新建一个Params.vue组件,包含参数
<template>
    <div>
        <h2>用户的ID是:{{this.$route.params.userId}}</h2>
    </div>
</template>
  • 新建Search.vue页面组件,包含带查询的参数
<template>
    <div>
        <h1>Search Result</h1>
        <p>搜索的内容是:{{this.$route.query.keyword}}</p>
    </div>
</template>
  • 新建一个codeChild.vue子组件
<template>
    <div>
        <h1>Code Child Page</h1>
    </div>
</template>
  • 新建一个包含codeChild的codeHome.vue组件
<template>
    <div>
        <h1>Code Home Page</h1>
        <!-- 子页面出口 -->
        <router-view></router-view>
    </div>
</template>
  • 在index.js文件添加路由关系表
    {
        path: "/codeHome",
        component:  CodeHome,
        children:[{
            path: "codeChild",
            name:"codeChild",
            component:  CodeChild
        }]  
    },
    {
        path: "/params/:userId",
        name:"userWithParam",
        component:  Params  
    },
    {
        path: "/search",
        name:"search",
        component:  Search  
    }
  • 新建Home.vue组件,定义跳转各路由的函数及按钮
<script setup>
    function toCodeHome(router){
        // 使用字符串作为路由参数
        router.push("/codeHome")
    }
    function toCodeChild(router){
        // 使用对象作为路由参数
        router.push({path:"/codeHome/codeChild"})
    }
    function toHomeNameWithParams(router){
        // 使用命名路由并带参数
        router.push({name:"userWithParam",params:{userId:123}})
    }
    function toSearch(router){
        // 使用命名路由并携带查询参数
        router.push({name:"search",query:{keyword:"樱桃毕罗"}})
    }

    function goFoward(router){
        router.go(1)
    }
    function goBack(router){
        router.go(-1)
    }
    function replaceNow(router){
        // router.replace("/ceshiren")
        router.push({path:"/ceshiren",replace:true})
    }
</script>

<template>
    <div>
        <h1>Home Page</h1>
        <p>
            <button @click="toCodeHome($router)" class="box">点击跳转path为/codeHome的路由地址</button>
        </p>
        <p>
            <button @click="toCodeChild($router)" class="box">点击跳转path为/codeHome/codeChild的路由地址</button>
        </p>
        <p>
            <button @click="toHomeNameWithParams($router)" class="box">点击跳转name为userWithParam的路由地址</button>
        </p>
        <p>
            <button @click="toSearch($router)" class="box">点击跳转name为search且包含参数查询的路由地址</button>
        </p>
        <p>
            <button @click="goFoward($router)" class="box">点击进入下一个页面</button>
        </p>
        <p>
            <button @click="goBack($router)" class="box">点击后退一页</button>
        </p>
        <p>
            <button @click="replaceNow($router)" class="box">替换路由到Ceshiren页面</button>
        </p>
        <router-view></router-view>
    </div>
</template>

<style scoped>
    .box{
        font-size:25px;
        margin-right: 30px;
    }
</style>
  • 根组件App.vue使用Home组件
<script setup>
   import Home from "./views/Home.vue"
</script>

<template>
   <Home></Home>
</template>

<style scoped>
    .box{
      font-size:25px;
      margin-right: 40px;
    }
</style>

六,导航守卫

6.1 简介

image
image
image
image
image

6.2 代码示例

  • index.js文件添加路由守卫
import { createRouter, createWebHashHistory } from "vue-router"
import Ceshiren from "../views/Ceshiren.vue"
import Hogwarts from "../views/Hogwarts.vue"
import NotFound from "../views/NotFound.vue"
import Child from "../views/NestChild.vue"
import User from "../views/NestUser.vue"
import Redirect from "../views/Redirect.vue"
import Alias from "../views/Alias.vue"
import Params from "../views/Params.vue"
import Search from "../views/Search.vue"
import CodeChild from "../views/CodeChild.vue"
import CodeHome from "../views/CodeHome.vue"

// 创建路由关系表
const routers=[
    {
        path: "/",
        component: Ceshiren
    },
    {
        path: "/ceshiren",
        name:"ceshiren",
        component: Ceshiren
    },
    {
        path: "/hogwarts/:id(\\d+)/:name([a-z]+)",
        component:  Hogwarts  
    },
    {
        path: "/user",
        // 命名路由
        name:"nestUser",
        component:  User, 
        children:[{
            // 子路由带动态参数的情况
            path: "child/:id/:name",
            name:"nestChild",
            component:  Child  
        }]
    },
    {
        path: "/macbookPro",
        // 通过路径重定向
        // redirect:{path: "/redirectPage"}
        // 通过名字重定向
        redirect: {name:"rp"}
    },
    {
        path: "/redirectPage",
        name:"rp",
        component:  Redirect  
    },
    {
        path: "/aliaspage",
        // 单个别名
        // alias:"/aliasName",
        // 多个别名
        alias:["/alias1", "/alias2", "/alias3"],
        component:  Alias  
    },
    {
        path: "/codeHome",
        component:  CodeHome,
        children:[{
            path: "codeChild",
            name:"codeChild",
            component:  CodeChild
        }]  
    },
    {
        path: "/params/:userId",
        name:"userWithParam",
        component:  Params  
    },
    {
        path: "/search",
        name:"search",
        component:  Search  
    },
    {
        path: "/:pathMatch(.*)*",
        component:  NotFound  
    }
]

// 创建路由对象
const router = createRouter({
    history: createWebHashHistory(),
    routes: routers
})

// 添加路由守卫
router.beforeEach((to,from) =>{
    console.log("BeforeEach —— From: ",from , "To: ", to);
    // return false  
    // return {path:"/"}     //会导致stack overflow栈溢出错误
    // if(to.name !="ceshiren"){
    //     return {name:"ceshiren"}
    // }
})

router.beforeResolve((to,from) =>{
    console.log("beforeResolve —— From: ",from , "To: ", to);
})

router.afterEach((to,from) =>{
    console.log("afterEach —— From: ",from , "To: ", to);
})

// 暴露路由
export default router