me

VueRouter


动态路由

在 Vue Router 中,我们可以在路径中使用一个动态字段来实现,我们称之为 路径参数

{
  path:"/user/:id",
  component:()=>import("../pages/User.vue")
}
<router-link to="/user/123">用户 123</router-link>

动态路由取值

在 template 中

<template>
  <div>
    <h2>用户界面:{{$route.params.id}}</h2>
  </div>
</template>

在 setup 中

import { useRoute } from "vue-router";
export default {
  setup() {
    const route = useRoute();
    console.log(route.params.id);
  },
};

匹配多个值

匹配模式匹配路径$route.params
/users/:user/users/lisi{ user: 'lisi' }
/users/:user/id/:id/users/:lisi/id/123{ user: 'lisi', id: '123' }

NotFound 页面

对于哪些没有匹配到的路由,可以编写一个动态路由将他们匹配到固定的某个页面

{
  path:"/:pathMatch(.*)",
  component:()=>import("../pages/NotFound.vue")
}

嵌套路由

使用嵌套路由配置来表达某些应用程序的 UI 由嵌套多级的组件组成

const routes = [
  {
    path: '/home',
    component: ()=>import("../pages/Home.vue"),
    children: [
      {
        path: '',
        redirect:"/home/product"//重定向
      },
      {
        path: 'product',
        component:component:()=>import("../pages/HomeProduct.vue"),
      },
    ],
  },
]

代码的页面跳转

声明式程序化
<router-link :to="...">router.push(...)

使用 router.push(...)

import { useRouter } from "vue-router";
export default {
  setup() {
    const router = useRouter();
    router.push({ name: "user", params: { username: "eduardo" } });
  },
};

替换当前位置

使用 push 的特点是压入一个新的页面,那么在用户点击返回时,上一个页面还可以回退,但是如果希望当前页面是一个替换操作,那么可以使用replace

声明式程序化
<router-link :to="..." replace>router.replace(...)

custom

custom 选项防止 <router-link> 将其内容包装在 <a> 元素内

默认情况下,<router-link> 将呈现其内容包裹在一个 <a> 元素,即使使用 v-slot。使用 custom,删除该行为

<router-link to="/home" custom v-slot="{navigate,href,route}">
  <a :href="href" @click="navigate">{{ route.fullPath }}</a>
</router-link>
<router-link
  to="/about"
  custom
  v-slot="{href,route,navigate,isActive,isExactActive}">
  <p @click="navigate">跳转 about</p>
  <div>
    <p>href:{{href}}</p>
    <p>route:{{route}}</p>
    <p>isActive:{{isActive}}</p>
    <p>isExactActive:{{isExactActive}}</p>    
  </div>
</router-link>

其它 api

参考https://next.router.vuejs.org/api/#aria-current-value

router-view

<router-view v-slot="{Component}">
  <transition name="why">
    <component :is="Component"></component>
  </transition>
</router-view>

动态的添加删除路由

添加路由

const about = {
  path: "id",
  component: () => import("../pages/About"),
};

router.addRoute("home", about);

删除路由

//添加一个 name 相同的路由
router.addRoute({ path: "/about", name: "about", component: About });
router.addRoute({ path: "/home", name: "about", component: Home });
//通过 removeRoute 方法,传入路由的名称
router.addRoute({ path: "/about", name: "about", component: About });
router.removeRoute("about");
//通过`addRoute`方法的返回值回调
const removeRoute = router.addRoute({
  path: "/about",
  name: "about",
  component: About,
});
removeRoute();

其他 API

Vue Router 将 RouterLink 的内部行为公开为 Composition API 函数。它提供访问与v-slotAPI 相同的属性

import { RouterLink, useLink } from "vue-router";
export default {
  name: "App",
  props: {
    ...RouterLink.props,
  },
  setup(props) {
    const { route, href, isActive, isExactActive, navigate } = useLink(props);
    return { href, navigate, isActive };
  },
};

路由守卫

路由守卫的触发时机

Vue router 提供的路由守卫主要用于通过重定向或取消路由来保护路由。有多种方法可以连接到路由导航过程:全局,每个路由或组件内

全局路由守卫 (beforeEach)

用来做一些进入页面的限制。比如没有登录,就不能进入某些页面,只有登录了之后才有权限查看某些页面 (初始化的时候被调用,每次路由切换之前被调用)

const router = createRouter({ ... })

router.beforeEach((to, from) => {
  // ...
  return false
})

路由独享守卫 (beforeEnter)

beforeEnter 守卫只在进入路由时触发不会在 params,query 或 hash 改变时触发

const routes = [
  {
    path: "/users/:id",
    component: UserDetails,
    beforeEnter: (to, from) => {
      return false;
    },
  },
];

全局后置后卫

不会接受返回值也不会改变导航本身。用于分析、更改页面标题、声明页面等辅助功能

router.afterEach((to, from) => {
  //...
})

组件内守卫

参考 https://next.router.vuejs.org/zh/guide/advanced/composition-api.html#%E5%AF%BC%E8%88%AA%E5%AE%88%E5%8D%AB