[TOC]
npm install vue-router@4 --save
  • useRoute 返回当前路由地址。相当于在模板中使用 $route。必须在 setup() 中调用。
  • useRouter 返回 router 实例。相当于在模板中使用 $router。必须在 setup() 中调用
  • useRouter().hasRoute() 检查路由是否存在
  • useRouter().getRoutes() 获取一个包含所有路由记录的数组

  • setup()以外的代码想使用router.push()等方法需要import 创建的路由实例(createRouter)即可

    import router from "../router";
    /* 加.then({})编辑器不会出现下划线提示 */
    router.push(path).then({})
    router.replace("/login").then({});
    

1-创建基础路由

  • router/index.js
import {createRouter, createWebHashHistory, createWebHistory} from "vue-router";
const routes = [
    {
        path:"/home",
        name:"home",
        component:()=>import("../view/Home")
    },
    {
        path:"/todo",
        name:"todo",
        component:()=>import("../components/todoList")
    },
    {
        /*  *通配符匹配404页面被移出 必须通过路径参数形式传进来才行 路径参数的名称随便写pathMatch 星号变成正则表达式 */
        path:"/:pathMatch(.*)*",
        name:"notFound",
        component:()=>import("../view/404")
    }
]

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

export default router;
  • main.js
import App from './App.vue'
import router from './router'

const app = createApp(App);
app.use(router);
app.mount('#app');

2-使用路由

<template>
  <router-link to="/home" tag="button">首页</router-link>
  <router-link to="/todo"  tag="button">todolist</router-link>
</template>
<script>
import { useRouter ,useRoute} from 'vue-router'
export default {
  //获取路由实例  useRouter 获取路由器,用来跳转
  const router = useRouter();

  //route是响应式变化 可监控变化
  const route = useRoute();
  watch( ()=>route.query,query =>{
       //测试  http://localhost:8080/#/home?too=111
       console.log('query',query);// {too=111}
   });

  function back(){
      //路由实例上的方法  相当如2.0的 this.$router.go(-1); //回退并且刷新页面
      router.back()
  };
  //跳转到指定页面  
  function back_home(){
      // router.push({
      //     path:'/home'
      // });
      router.push('/home')
  }
  return {
      back,
      back_home,
  }
}

</script>

3-addRoute动态添加多条路由或者单条子路由

router.addRoute({
    path:"/about",
    name:"about",
    component:()=>import("../view/about")
})
// 向name为about路由下边添加子路由
router.addRoute('about',{
    path:"/aboutInfo",
    name:"aboutInfo",
    component:()=>import("../view/aboutInfo")
})

4-动态删除路由

  • 方式一:添加一个name相同的路由;这会删除之前已添加的路由,因为具备名字的唯一性
  • 方式二:通过removeRoute方法,传入路由的名称name;
 router.removeRoute('about')

5-router-link 4.x变化

  • router-link 组件支持用户在具有路由功能的应用中(点击)导航。 通过 to 属性指定目标地址,默认渲染成带有正确链接的 标签
  • 2.0可以通过配置 tag 属性生成别的标签(4.x该属性被移除了)
// 讲router-link渲染为指定的标签
<router-link :to="{name:'cart'}" tag="button">
    cart
</router-link>
  • 4.x替换成 custom (我要自定义 不在用默认的a标签)配合v-slot使用
  • 默认情况下, 会将其内容包裹在 元素中,即使使用 v-slot 也是如此。传递自定义的 prop可以去除这种行为
// 我们使用v-slot来作用域插槽来获取内部传给我们的值
  href:解析后的 URL;
  route:解析后的规范化的route对象;
  navigate:触发导航的函数;
  isActive:是否匹配的状态;
  isExactActive:是否是精准匹配的状态;
  <router-link to="/todo" v-slot="props" custom>
      <button @click="props.navigate">{{props.route.name}}</button>
      <span :class="{'active':props.isActive}">{{props.isActive}}</span>
  </router-link>

6-导航守卫

完整的导航解析流程

  • 导航被触发。
  • 在失活的组件里调用 beforeRouteLeave 守卫。
  • 调用全局的 beforeEach 守卫。
  • 在重用的组件里调用 beforeRouteUpdate 守卫(2.2+)。
  • 在路由配置里调用 beforeEnter。
  • 解析异步路由组件。
  • 在被激活的组件里调用 beforeRouteEnter。
  • 调用全局的 beforeResolve 守卫(2.5+)。
  • 导航被确认。
  • 调用全局的 afterEach 钩子。
  • 触发 DOM 更新。
  • 调用 beforeRouteEnter 守卫中传给 next 的回调函数,创建好的组件实例会作为回调函数的参数传入。
<template>
    <div>
       路由离开后调用onBeforeRouteLeave
    </div>
</template>
<script>
    import { onBeforeRouteLeave , onBeforeRouteUpdate} from 'vue-router'
    export default {
        name: "aboutInfo",
        setup(){
            onBeforeRouteLeave((to,from)=>{
                console.log('路由离开',to,from);
            })
        }
    }
</script>

7-router-view 4.x变化 (路由缓存及动画)

  • 2.0写法
<keep-alive>
    <router-view></router-view>
<keep-alive>
  • router-view也提供给我们一个插槽,可以用于 和 组件来包裹你的路由组件:
  • 4.x transition、keep-alive必须在router-view标签内部

Component:要渲染的组件;
route:解析出的标准化路由对象;

<template>
    <router-view v-slot="{ Component }">
        <template v-if="Component">
            // transition动画
            <transition name='why'>
                <keep-alive>
                    <component :is="Component"></component>
                </keep-alive>
            </transition>
        </template>
    </router-view>
</template>
<style>
    .why-active{
        color: red;
    }
    .why-enter-from,
    .why-leave-from{
        opacity: 0;
    }
    .why-enter-active,
    .why-leave-activem{
        transition: opacity 1s ease;
    }
</style>

keep-alive 路由缓存

include - string | RegExp | Array。只有名称匹配的组件会被缓存。
exclude - string | RegExp | Array。任何名称匹配的组件都不会被缓存。
max - number | string。最多可以缓存多少组件实例。

8-破坏性变化

所有的导航现在都是异步的

  • 所有的导航,包括第一个导航,现在都是异步的,这意味着,如果你使用一个 transition,你可能需要等待路由 ready 好后再挂载程序
import { createApp } from 'vue'
import App from './App.vue'
const app = createApp(App);
app.use(router)
// 注意:在服务器端,你需要手动跳转到初始地址。
router.isReady().then(() => app.mount('#app'))

new Router 变成 createRouter
新的 history 配置取代 mode

  • mode: ‘history’ 配置已经被一个更灵活的 history 配置所取代。根据你使用的模式,你必须用适当的函数替换它:
"history": createWebHistory()
"hash": createWebHashHistory()
"abstract": createMemoryHistory()
  • 2.0
import Vue from "vue";
import VueRouter from "vue-router";
Vue.use(VueRouter);
export const constantRoutes = []

const router = new VueRouter({
    mode: 'hash'
    routes: constantRoutes
});

export default router;
  • 4.x
import {createRouter, createWebHashHistory, createWebHistory} from "vue-router";
const routes = []
const router = createRouter({
     history: createWebHashHistory(),
     routes,
)}

移动了 base 配置

  • 现在,base 配置被作为 createWebHistory (其他 history 也一样)的第一个参数传递
import { createRouter, createWebHistory } from 'vue-router'
createRouter({
  // http://localhost:8080/base-directory/routerName 
  history: createWebHistory('/base-directory/'),
  routes: [],
})
  • 删除了 *(星标或通配符)路由

记录滚动位置


const router = createRouter({
    history: createWebHashHistory(),
    routes,
    /*记录滚动位置*/
    scrollBehavior(to,from,savedPosition){
        // {x:10,y:10}    now  {left:10,top:10}
        if(savedPosition){
            return savedPosition
        }else{
            return {
                top:0
            }
        }
    },
});

面包屑导航

  • 通过路由匹配数组可以动态生成面包屑 ```vue

``` 别忘了添加依赖:path-to-regexp
注意:vue-router4 已经不再使用path-to-regexp解析动态path,因此这里后续还需要改进。