Vue3-Vue-Router

313 阅读3分钟

一、前端路由发展历程

1. 后端路由阶段

  • 服务器直接渲染好对应的HTML页面,返回给客户端进行展示
    • 一个页面有自己对应的网址,也就是URL
    • URL会发送到服务器,服务器会通过正则对该URL进行匹配,并且最后交给一个Controller进行处理
    • Controller进行各种处理,最终生成HTML或者数据,返回给前端

2. 前后端分离阶段

  • 后端只提供API来返回数据,前端通过Ajax获取数据,并且可以通过JavaScript将数据渲染到页面上

3. 单页面富应用阶段

  • 在前后端分离的基础上加了一层前端路由
    • 也就是前端来维护一套路由规则
    • 前端路由的核心:改变URL,但是页面不进行整体的刷新

二、Vue-Router基本使用

1. 认识vue-router

  • vue-router是基于路由和组件的
  • 路由用于设定访问路径,将路径和组件映射起来
  • 在vue-router的单页面应用中,页面的路径的改变就是组件的转换

2. 路由的使用步骤

  • 第一步:创建路由需要映射的组件
  • 第二步:通过createRouter创建路由对象,听取传入routes和history模式
  • 第三步:通过app注册路由对象
  • 第四步:通过和使用路由
    import { createRouter, createWebHashHistory } from "vue-router"
    import Home from "../pages/Home.vue"
    import About from "../pages/About.vue"
    const router = createRouter({
        history: createWebHashHistory(),
        // 将根路径重定向
        {
            path: "/",
            redirect: "/home"
        },
        { 
            // 路由记录独一无二的名称
            name: "home"
            path: "/home", 
            component: Home,
            // 自定义的数据
            meta: {
                name: "Messi",
                age: 18
            }
        },
        { 
            path: "/about", 
            component: About
        }
    })
    export default router
    

3. router-link属性

  • to属性
  • replace属性
  • active-class属性
  • exact-active-class属性
    <template>
        <div class="app">
            <p>
                <router-link to="/home">首页</router-link>
                <router-link to="/about">关乎</router-link>
            </p>
            <router-view></router-view>
        </div>
    </template>
    

三、路由懒加载分包处理

// component可以传入一个组件,也可以接收一个函数,该函数需要返回一个Promise
// 而import函数就是返回一个Promise
const routes = [
    { path: "/", redirect: "/home" },
    { path: "/home", component: () => import("../pages/Home.vue") },
    { path: "/about", component: () => import("../pages/About.vue") }
]

四、动态路由和路由嵌套

1. 动态路由

  • 动态路由基本匹配
{
    path: "/user/:id/",
    component: () => import("../pages/User.vue")
}

2. 获取动态路由的值

  • template中,直接通过$route.params获取值
  • created中,通过this.$route.params获取值
  • setup中,通过vue-router库给我们提供一个hook useRoute
export default {
    created() {
        console.log(this.$route.params.id)
    },
    setup() {
        const route = useRoute()
        console.log(route.params.id)
    }
}

3. 路由的嵌套

{
    path: "/home",
    component: () => import(/*webpackChunkName: "home-chunk"*/"../pages/Home.vue"),
    children: [
        {
            path: "",
            redirect: "/home/product"
        },
        {
            path: "product",
            component: () => import("../pages/HomeProduct.vue")
        }
    ]
}

4. 页面的跳转

export default {
    created() {
        this.$router.push({
            path: "/home/product",
            query: {
                name: "why",
                age: 18
            }
        })
    },
    setup() {
        const router = useRouter()
        router.replace("/home/product")
    }
}

五、动态管理路由对象

1. 动态添加路由

const categoryRoute = {
    path: "/category",
    component: () => import("../pages/Category.vue")
}
router.addRoute(categoryRoute)
// 如果是为route添加一个children路由,那么可以传入对应的name
router.addRoute("home", categoryRoute)

2. 删除路由的三种方式

  • 方式一:添加一个name相同的路由
  • 方式二:通过removeRoute方法,传入路由的名称
  • 方式三:通过addRoute方法返回值回调
// 方法一
router.addRouter({ path: "/about", name: "about", component: About })
router.addRouter({ path: "/other", name: "about", component: Other })
// 方法二
router.addRouter({ path: "/about", name: "about", component: About })
router.removeRoute("about")
// 方法三
const removeRoute = router.addRouter({ path: "/about", name: "about", component: About })
removeRoute()

3. 路由其他方法

  • router.hasRouter()
    • 检查路由是否存在
  • router.getRoutes()
    • 获取一个包含所有路由记录的数组

六、路由导航守卫钩子

1. 路由导航首位

  • vue-router提供的导航守卫主要用来通过跳转或取消的方式守卫导航
  • 全局的前置首位beforeEach是在导航出发时会被回调的
  • 两个参数
    • to:即将进入的路由Route对象
    • form:即将离开的路由Route对象
  • 返回值
    • false:取消当前导航
    • 不返回或者undefined进行默认导航
    • 返回一个路由地址

2. 登录守卫功能

router.beforeEach((to, from) => {
  if (to.path !== "/login") {
    const token = window.localStorage.getItem("token")
    if (!token) {
        return {
            path: "/login"
        }
    }
  }
})

3. 导航守卫流程

router.vuejs.org/zh/guide/ad…

  • 导航被触发
  • 在失活的组件里调用beforeRouteLeave守卫
  • 调用全局的beforeEach守卫
  • 在重用的组件里调用beforeRouteUpdate守卫
  • 在路由配置里调用beforeEnter
  • 解析异步路由组件
  • 在被激活的组件里调用beforeRouteEnter
  • 调用全局的beforeResolve守卫
  • 导航被确认
  • 调用全局的afterEach钩子
  • 触发DOM更新
  • 调用beforeRouteEnter守卫中传给next的回调函数,创建好的组件实例会作为回调函数的参数传入