【vue3 路由使用与讲解】vue-router : 超详细全面介绍

# 核心内容介绍

路由跳转有两种方式:

  • 声明式导航:<router-link :to="...">

  • 编程式导航:router.push(...) 或 router.replace(...) ;两者的规则完全一致。

    • push(to: RouteLocationRaw): Promise<NavigationFailure | void | undefined>

      replace(to: RouteLocationRaw): Promise<NavigationFailure | void | undefined>;

  • 由于属性 torouter.push 接受的对象种类相同,所以两者的规则完全相同。

路由传参有两种方法:

  • params:使用动态路由的方式进行传参;
    • 只为了传参则不建议用params,params 主要是用来进行动态路由匹配的。
    • 声明为动态路由,params则是必传的!除非设置为可选!
    • 声明路由时设置该路由props参数为true,则会改变功能形态。(傻逼功能,别用)
  • query:拼接在url后面,以?的方式隔开;/urlpath?d1="666"&d2=逆天&arr=["1"]&b=true
    • 传参时仅建议 string | number | (string|number)[] 类型的数据 ,否则编辑器会 ts 报错提示。
  • 所有传参的数据类型如果非字符串会自动字符串化 >> String(xx)
  • params 和 query 的 TS 类型为:string | string[]。也就意味着它并不希望你放乱七八糟的东西在url上,即便你JSON.stringify() 转换过了。

动态路由:

  • 动态路由的跳转必须是 name + params,用 path 跳转命名路由将无效;且 params 必传!
  • 动态路由以 `/path1/:id` 的方式进行声明,跳转路径结果为 /path/1
  • 动态路由设置的参数例如 :id ,可以将该参数设置为可选参数 `/path1/:id?` ,这样params就是可传可不传了。

命名路由:

  • 就是声明了路由的 name。name值是唯一的,不管是顶级路由还是嵌套路由。
  • 如果是跳转嵌套路由里的子路由,path 跳转需要/xx/xx/child,可直接用该子路由的name。
  • 没有硬编码的 URL
  • params 的自动编码/解码。
  • 防止你在 url 中出现打字错误。
  • 绕过路径排序(如显示一个)

# 说明:

$route / route: 有当前路由的所有信息!

$router / router: 用来进行路由操作的!


# 声明路由

如何声明路由

  • 必备的 path component。其他一堆属性自己了解相关功能就知道什么时候是必要的,什么时候是非必要的了。有用点的就是name redirect children meta了。

顶级路由

  • 最外层的路由

嵌套路由

  • 声明路由的 children
  • 嵌套路由不限层级
  • 想要默认加载一个子路由的话将path设置为空字符串:` path:"" `。
  • 跳转嵌套路由最好使用 name 方式跳转,降低心智负担!

声明为动态路由,上面讲过了,忘了?别怕,那下面代码也有示例。

路由重定向

  • redirect: { name: 'routeName' }, 设置为路由的name最保险,别想着其他花里胡哨的。

  • 在写 redirect 的时候,如果不是嵌套路由,可以省略 component 配置。
    你重定向到自己的子路由,那肯定要有 component 啊,不然你 router-view 在哪(笑)

命名视图

  • component 变 components,具体看代码

  • 本示例包含 path , name , meta , component , components , children , redirect , props , 路由懒加载 , alias 。

javascript 复制代码
import { createRouter, createWebHistory } from 'vue-router'

export const router = createRouter({
  history: createWebHistory(), // 设置路由模式
  routes: [
    {
      // 普通的设置一个普通的路由(顶级路由)
      path: '/',
      name: 'HelloWorld',
      meta: { requiresXXX: true }, // 设置路由元信息,应用场景的话:主要就路由守卫里用的会多一点。该数据只能在这里声明,其他途径无法修改。
      component: () => import('../components/HelloWorld.vue') // 设置路由懒加载
    },
    {
      path: '/routerVue/:id', // 设置为动态路由,id则必传
      // path: '/routerVue/:id?', // 设置该动态路由的 id 为可选参数,变为非必传
      name: 'routerVue',
      component: () => import('@/components/xxx.vue')
    },
    {
      path: '/demo',
      alias: '/hellow', // 你访问 /hellow,页面url路径会保持为/hellow,但是路由匹配则为/demo,显示 yyyyyy.vue 组件内容
      component: () => import('@/components/yyyyyy.vue')
    },
    {
      path: '/edit:id?',
      name: 'edit',
      // redirect: { name: 'profile' }, // 路由重定向,访问 /edit 直接重定向为 /edit/profile
      component: () => import('../components/edit.vue'),
      props: true, // 设置为true 则在路由组件中,动态路由的参数 会直接放在vue的 props 里。 // 完全不推荐的写法,增加心智负担。
      children: [ // 设置为嵌套路由
        {
          // 当 /edit 匹配成功
          // demo2.vue 将被渲染到 edit 的 <router-view> 内部
          path: '', // 路径为'',需要增加name,不然会抛出警告。
          component: () => import('../components/demo2.vue'),
          // 命名视图功能: component 变为 components ,然后设置对应视图组件的名称
          // components:{ // 注意加 s 。。。
          //   default: () => import('../components/router-test1.vue'),
          //   template1: () => import('../components/router-test2.vue'),
          // },
          // props: {default: true , template1: false} // 可以为每个命名视图定义 props 配置。还可设置为函数模式(超不推荐,提高代码维护理解难度,对功能方面没任何提升)
        },
        {
          // 当 /edit/profile 匹配成功
          // demo.vue 将被渲染到 edit 的 <router-view> 内部
          path: 'profile',
          name: 'profile',
          component: () => import('../components/profile.vue'),
        }]
    },
    {
      // 匹配所有路径,当上述路径都不满足时,跳转到404页面
      // 如果项目是有动态添加路由的,注意一定要把该404路由提取出来,等动态添加完路由,再把404添加到动态路由的最后一个。
      path: '*',
      name: '404',
      component: () => import('../components/404.vue'),
    },
  ],
})

# 路由跳转的多种写法:

声明式导航写法:

html 复制代码
<router-link :to="{ name: 'vue33', params: { id: 110 }, query: { d1: 'wuwu~~~' } }">vue3.3/3.4新特性</router-link>

编程式导航写法:(options api里的方式)

javascript 复制代码
this.$router.push({
  name: 'vue33',
  params: {
    id: 110
  },
  query: {
    data: 666
  }
})

编程式导航写法:(composition api里的方式)

javascript 复制代码
import { useRouter  } from 'vue-router'
let router = useRouter()
function tiaozhuan() {
  router.push({
    name: 'vue33',
    params: {
      id: 110
    },
    query: {
      data: 666
    }
  })
}

replace 是当前页面替换新页面,路由历史记录里不会保存当前页。

javascript 复制代码
import { useRouter  } from 'vue-router'
let router = useRouter()
function tiaozhuan() {
  router.replace({
    name: 'vue33',
    params: {
      id: 110
    },
    query: {
      data: 666
    }
  })
}

如果是嵌套路由则是父路由path + 子路由path,或者子路由的name,并且跳转时,如果父路由是命名路由,则params也会是必传!


# 获取路由参数

跳转目标路由,声明了params或query之后,(选项式api写法) 通过this.route.params 或 this.route.query 即可拿到对应的路由参数;

组合式API写法如下:

javascript 复制代码
import { useRoute } from 'vue-router'

let route = useRoute()

console.log(route.params);
console.log(route.query);
console.log(route.meta);

# 重新提醒:

route: 有当前路由的所有信息

router: 用来进行路由操作的!


# 路由的导航守卫

  • 全局守卫;

    • beforeEach :全局前置守卫 (1)
    • beforeResolve :全局解析守卫 (3)
    • afterEach:全局后置钩子,该钩子在已经进入该路由后触发,所以无需return true 或 next()。 (4)
  • 路由独享的守卫:

    • beforeEnter :在所有组件内守卫和异步路由组件被解析之后调用。(2)
  • 组件守卫:有3个,其中2个没屁用。

    • beforeRouteEnter :能处理的 beforeEnter 都可以。

    • beforeRouteUpdate :更没必要,直接 watch route.params 即可。

    • beforeRouteLeave :有点用,如果用户跳转路由时,当前页面编辑内容未保存,则可以 return false 取消路由跳转。(setup 内则手动引入 onBeforeRouteLeave)

  • 触发顺序(1)(2)(3)(4)。

    • 组件守卫其中2个懒得算,如果算上 beforeRouteLeave 那 beforeRouteLeave 排在beforeEach 前面。

每个守卫方法接收两个参数:

  • to: 即将要进入的目标 。
  • from: 当前导航正要离开的路由 。
  • next: 可选的第三个参数 。(现在根据return 结果来决定了,且更安全(确保调用一次),所以基本不需要next了)
javascript 复制代码
import { createRouter } from 'vue-router'
const router = createRouter({ ... })

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

  return false  
  // 返回 false 以取消导航
  // 如果什么都没有,undefined 或返回 true,则导航是有效的,并调用下一个导航守卫

  // return { name: 'Login' } // 将用户重定向到登录页面
})

# 动态添加路由

javascript 复制代码
//! 动态添加路由、删除路由、添加嵌套路由
router.addRoute({ path: '/about', component: xxx })

// 当路由被删除时,所有的别名和子路由也会被同时删除
// 会返回一个回调,调用该函数即可删除路由 (这种方式可以保证删的更准点吧。。。)
const removeRoute = router.addRoute({ path: '/about', component: xxx })
removeRoute()
// router.removeRoute('about') 通过路由名称进行删除,路由表有同名的话需要注意点(建议路由表name都是唯一的!)

// 添加嵌套路由
// router.addRoute({ name: 'admin', path: '/admin', component: Admin })
// router.addRoute('admin', { path: 'settings', component: AdminSettings })
//> 上述代码等同如如下:
// router.addRoute({
//   name: 'admin',
//   path: '/admin',
//   component: Admin,
//   children: [{ path: 'settings', component: AdminSettings }],
// })

# 查看现有路由

Vue Router 提供了两个功能来查看现有的路由:


# 路由缓存、过渡

<router-view>、<keep-alive> 和 <transition>​

transition 和 keep-alive 现在必须通过 v-slot API 在 RouterView 内部使用:

html 复制代码
<router-view v-slot="{ Component }">
  <transition>
    <keep-alive>
      <component :is="Component" />
    </keep-alive>
  </transition>
</router-view>

# 路由模式

  • Hash 模式:createWebHashHistory
  • HTML5 模式:createWebHistory
javascript 复制代码
import { createRouter, createWebHashHistory } from 'vue-router'
const router = createRouter({
  history: createWebHashHistory(),
  routes: [
    //...
  ],
})

html5模式需要在服务器上设置初次访问如果404时,进行路由回退:

nginx 如下:

bash 复制代码
location / {
  try_files $uri $uri/ /index.html;
}

其他的详见官网;

相关推荐
崔庆才丨静觅12 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅12 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅13 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment13 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅13 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊13 小时前
jwt介绍
前端
爱敲代码的小鱼13 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax
吹牛不交税13 小时前
admin.net-v2 框架使用笔记-netcore8.0/10.0版
vue.js·.netcore
Cobyte13 小时前
AI全栈实战:使用 Python+LangChain+Vue3 构建一个 LLM 聊天应用
前端·后端·aigc
NEXT0614 小时前
前端算法:从 O(n²) 到 O(n),列表转树的极致优化
前端·数据结构·算法