vue-router 版本为4的是为vue3准备的
如果是vue2 安装版本为vue-router@3
1. 基础用法
// router -> index.js import { createRouter, createWebHistory } from "vue-router"; let router = createRouter({ history: createWebHistory(), routes: [ { path: "/login", name: "login", component: () => import("@/views/login.vue"), }, ], scrollBehavior() { return { el: "#app", top: 0, behavior: "smooth", }; }, }); export default router; // main.js import router from "./router/index.js"; const app = createApp(App); app.use(router); // App.vue <router-view></router-view>;
2. 路由跳转
<router-link to="/">Go to Home</router-link> <router-link to="/about">Go to About</router-link>
import { useRouter } from "vue-router"; let router = useRouter(); // 字符串路径 router.push("/users/eduardo"); // 带有路径的对象 router.push({ path: "/users/eduardo" }); // 命名的路由,并加上参数,让路由建立 url router.push({ name: "user", params: { username: "eduardo" } }); // 带查询参数,结果是 /register?plan=private router.push({ path: "/register", query: { plan: "private" } }); // 带 hash,结果是 /about#team router.push({ path: "/about", hash: "#team" }); // 注意:如果提供了 path,params 会被忽略,上述例子中的 query 并不属于这种情况。取而代之的是下面例子的做法,你需要提供路由的 name 或手写完整的带有参数的 path const username = "eduardo"; // 我们可以手动建立 url,但我们必须自己处理编码 router.push(`/user/${username}`); // -> /user/eduardo // 同样 router.push({ path: `/user/${username}` }); // -> /user/eduardo // 如果可能的话,使用 `name` 和 `params` 从自动 URL 编码中获益 router.push({ name: "user", params: { username } }); // -> /user/eduardo // `params` 不能与 `path` 一起使用 router.push({ path: "/user", params: { username } }); // -> /user ```
3. 动态路由
// router->index.js const routes = [{ path: "/user/:id", component: User }]; // User组件 获取参数 url: user/1 import { useRoute } from "vue-router"; let route = useRoute(); console.log(route.params); // { id: 1 }
<!-- template 中获取url参数 --> {{ $route.params }}
4. 嵌套路由
const routes = [ { path: "/user/:id", component: User, children: [ { // 当 /user/:id/profile 匹配成功 // UserProfile 将被渲染到 User 的 <router-view> 内部 path: "profile", component: UserProfile, }, { // 当 /user/:id/posts 匹配成功 // UserPosts 将被渲染到 User 的 <router-view> 内部 path: "posts", component: UserPosts, }, ], }, ];
5. 命名路由
// 除了 path 之外,你还可以为任何路由提供 name const routes = [ { path: "/user/:username", name: "user", component: User, }, ];
6. 命名视图
const router = createRouter({ history: createWebHashHistory(), routes: [ { path: "/", components: { default: Home, // LeftSidebar: LeftSidebar 的缩写 LeftSidebar, // 它们与 `<router-view>` 上的 `name` 属性匹配 RightSidebar, }, }, ], });
<router-view class="view left-sidebar" name="LeftSidebar"></router-view> <router-view class="view main-content"></router-view> <router-view class="view right-sidebar" name="RightSidebar"></router-view>
7. 重定向
const routes = [{ path: "/home", redirect: "/" }]; const routes = [{ path: "/home", redirect: { name: "homepage" } }]; const routes = [ { // /search/screens -> /search?q=screens path: "/search/:searchText", redirect: (to) => { // 方法接收目标路由作为参数 // return 重定向的字符串路径/路径对象 return { path: "/search", query: { q: to.params.searchText } }; }, }, { path: "/search", // ... }, ]; const routes = [ { // 将总是把/users/123/posts重定向到/users/123/profile。 path: "/users/:id/posts", redirect: (to) => { // 该函数接收目标路由作为参数 // 相对位置不以`/`开头 // 或 { path: 'profile'} return "profile"; }, }, ];
8. 别名
// 当用户访问 /home 时,URL 仍然是 /home,但会被匹配为用户正在访问 / const routes = [{ path: "/", component: Homepage, alias: "/home" }];
9. 路由组件传参
const User = { // 请确保添加一个与路由参数完全相同的 prop 名 props: ["id"], template: "<div>User {{ id }}</div>", }; const routes = [{ path: "/user/:id", component: User, props: true }]; // 有命名视图得路由 const routes = [ { path: "/user/:id", components: { default: User, sidebar: Sidebar }, props: { default: true, sidebar: false }, }, ];
10. 导航守卫
const router = createRouter({ ... }) router.beforeEach((to, from) => { // ... // 返回 false 以取消导航 return false })
// false: 取消当前的导航。 // 一个路由地址: 通过一个路由地址跳转到一个不同的地址。 // 如果什么都没有,undefined 或返回 true,则导航是有效的 router.beforeEach(async (to, from) => { if ( // 检查用户是否已登录 !isAuthenticated && // ❗️ 避免无限重定向 to.name !== "Login" ) { // 将用户重定向到登录页面 return { name: "Login" }; } });
// 全局解析守卫, 确保用户可以访问自定义 meta 属性 router.beforeResolve(async (to) => { if (to.meta.requiresCamera) { try { await askForCameraPermission(); } catch (error) { if (error instanceof NotAllowedError) { // ... 处理错误,然后取消导航 return false; } else { // 意料之外的错误,取消导航并把错误传给全局处理器 throw error; } } } });
// 全局后置钩子,它们对于分析、更改页面标题、声明页面等辅助功能以及许多其他事情都很有用 router.afterEach((to, from) => { sendToAnalytics(to.fullPath); });
11. 路由元信息
// 有时,你可能希望将任意信息附加到路由上,如过渡名称、谁可以访问路由等,并且它可以在路由地址和导航守卫上都被访问到 const routes = [ { path: '/posts', component: PostsLayout, children: [ { path: 'new', component: PostsNew, // 只有经过身份验证的用户才能创建帖子 meta: { requiresAuth: true } }, { path: ':id', component: PostsDetail // 任何人都可以阅读文章 meta: { requiresAuth: false } } ] } ] router.beforeEach((to, from) => { // 而不是去检查每条路由记录 // to.matched.some(record => record.meta.requiresAuth) if (to.meta.requiresAuth && !auth.isLoggedIn()) { // 此路由需要授权,请检查是否已登录 // 如果没有,则重定向到登录页面 return { path: '/login', // 保存我们所在的位置,以便以后再来 query: { redirect: to.fullPath }, } } })
12. 过渡效果
const routes = [ { path: "/custom-transition", component: PanelLeft, meta: { transition: "slide-left" }, }, { path: "/other-transition", component: PanelRight, meta: { transition: "slide-right" }, }, ];
<router-view v-slot="{ Component, route }"> <!-- 使用任何自定义过渡和回退到 `fade` --> <transition :name="route.meta.transition || 'fade'"> <component :is="Component" /> </transition> </router-view>
/* 进入和离开动画可以使用不同 持续时间和速度曲线。 */ .slide-left-enter-active { transition: all 0.3s ease-out; } .slide-left-leave-active { transition: all 0.8s cubic-bezier(1, 0.5, 0.8, 1); } .slide-left-enter-from, .slide-left-leave-to { transform: translateX(20px); opacity: 0; } /* 动画 */ .slide-left-enter-active { animation: bounce-in 0.5s; } .slide-left-leave-active { animation: bounce-in 0.5s reverse; } @keyframes bounce-in { 0% { transform: scale(0); } 50% { transform: scale(1.25); } 100% { transform: scale(1); } }
13. 滚动行为
const router = createRouter({ history: createWebHashHistory(), routes: [...], scrollBehavior (to, from, savedPosition) { // return 期望滚动到哪个的位置 } }) const router = createRouter({ scrollBehavior(to, from, savedPosition) { // 始终滚动到顶部 return { top: 0 } }, }) // 你也可以通过 el 传递一个 CSS 选择器或一个 DOM 元素。在这种情况下,top 和 left 将被视为该元素的相对偏移量。 const router = createRouter({ scrollBehavior(to, from, savedPosition) { // 始终在元素 #main 上方滚动 10px return { // 也可以这么写 // el: document.getElementById('main'), el: '#main', top: -10, } }, }) // 如果你的浏览器支持滚动行为,你可以让它变得更流畅 const router = createRouter({ scrollBehavior(to, from, savedPosition) { if (to.hash) { return { el: to.hash, behavior: 'smooth', } } } })