当前位置:   article > 正文

VUE3 路由学习(一)

vue3 路由

一、基础入门

1.1入门

 首先我们要知道两个标签  一个是 router-link(入口和router-view(出口)。

  1. <div id="app">
  2. <h1>Hello App!</h1>
  3. <p>
  4. <!--使用 router-link 组件进行导航 -->
  5. <!--通过传递 `to` 来指定链接 -->
  6. <!--`<router-link>` 将呈现一个带有正确 `href` 属性的 `<a>` 标签-->
  7. <router-link to="/">Go to Home</router-link>
  8. <router-link to="/about">Go to About</router-link>
  9. </p>
  10. <!-- 路由出口 -->
  11. <!-- 路由匹配到的组件将渲染在这里 -->
  12. <router-view></router-view>
  13. </div>

1.2 使用步骤

  1. // 1. 定义路由组件.
  2. // 也可以从其他文件导入
  3. const Home = { template: '<div>Home</div>' }
  4. const About = { template: '<div>About</div>' }
  5. // 2. 定义一些路由
  6. // 每个路由都需要映射到一个组件。
  7. // 我们后面再讨论嵌套路由。
  8. const routes = [
  9. { path: '/', component: Home },
  10. { path: '/about', component: About },
  11. ]
  12. // 3. 创建路由实例并传递 `routes` 配置
  13. // 你可以在这里输入更多的配置,但我们在这里
  14. // 暂时保持简单
  15. const router = VueRouter.createRouter({
  16. // 4. 内部提供了 history 模式的实现。为了简单起见,我们在这里使用 hash 模式。
  17. history: VueRouter.createWebHashHistory(),
  18. routes, // `routes: routes` 的缩写
  19. })
  20. // 5. 创建并挂载根实例
  21. const app = Vue.createApp({})
  22. //确保 _use_ 路由实例使
  23. //整个应用支持路由。
  24. app.use(router)
  25. app.mount('#app')
  26. // 现在,应用已经启动了!

通过调用 app.use(router),我们会触发第一次导航且可以在任意组件中以 this.$router 的形式访问它,并且以 this.$route 的形式访问当前路由:

  1. // Home.vue
  2. export default {
  3. computed: {
  4. username() {
  5. // 我们很快就会看到 `params` 是什么
  6. return this.$route.params.username
  7. },
  8. },
  9. methods: {
  10. goToDashboard() {
  11. if (isAuthenticated) {
  12. this.$router.push('/dashboard')
  13. } else {
  14. this.$router.push('/login')
  15. }
  16. },
  17. },
  18. }

要在 setup 函数中访问路由,因为没有this 所以请调用 useRouter 或 useRoute 函数。

二、动态路由匹配

2.1 带参数的动态路由匹配

  1. const User = {
  2. template: '<div>User</div>',
  3. }
  4. // 这些都会传递给 `createRouter`
  5. const routes = [
  6. // 动态字段以冒号开始
  7. { path: '/users/:id', component: User },
  8. ]

其中的id 就是路由参数  /users/1 和 /users/2  这样的URL 都会映射到同一个路由。

路径参数 用冒号 :  表示  当一个路由匹配时,他的params的值将在每一个组件中以 this.$route.params 的形式暴露出来  因为 我们可以这样访问到:

  1. const User = {
  2. template: '<div>User {{ $route.params.id }}</div>',
  3. }

我们也可以在同一个路由设置多个路径参数 都会映射在 $route.params上:

/users/:username/posts/:postId====>/users/eduardo/posts/123===>{ username: 'eduardo', postId: '123' }

除了 $route.params 之外,$route 对象还公开了其他有用的信息,如 $route.query(如果 URL 中存在参数)、$route.hash 等

2.2 响应路由参数的变化

当携带有路由参数的时候  说明这个路由可能会被复用  因为都是渲染同一个组件 比起销毁在创建 复用更高效  不过这也意味着组件的生命周期钩子不会被调用  所以要对同一个组件的参数变化做出响应  你可以简单地watch $route 对象上的任意属性 在这个场景下 就是 $route.params:

  1. const User = {
  2. template: '...',
  3. created() {
  4. this.$watch(
  5. () => this.$route.params,
  6. (toParams, previousParams) => {
  7. // 对路由变化做出响应...
  8. }
  9. )
  10. },
  11. }

或者,使用 beforeRouteUpdate 导航守卫,它也可以取消导航:

  1. const User = {
  2. template: '...',
  3. async beforeRouteUpdate(to, from) {
  4. // 对路由变化做出响应...
  5. this.userData = await fetchUser(to.params.id)
  6. },
  7. }

三、路由的匹配语法

3.1在参数中自定义正则

当我们在路由路径上匹配的时候   有两个路由 /:orderId  和  /:productName,两者会匹配完全相同的URL,那么我们需要区分他们 最简单的方式 就是在路径起那么添加一个静态部分来区分:

  1. const routes = [
  2. // 匹配 /o/3549
  3. { path: '/o/:orderId' },
  4. // 匹配 /p/books
  5. { path: '/p/:productName' },
  6. ]

但是又比如说 我们不想用这种方式 毕竟这种方式会让地址变得不好看  而且orderId总是一个数字 而 productName 可以是任何东西 所以我们可以在括号中为参数指定一个自定义的正则:

  1. const routes = [
  2. // /:orderId -> 仅匹配数字
  3. { path: '/:orderId(\\d+)' },
  4. // /:productName -> 匹配其他任何内容
  5. { path: '/:productName' },
  6. ]

如果是 /25将匹配到 ‘/:orderId’,其他情况将会匹配 /:productName, route数组顺序并不重要。

3.2可重复的参数

如果你需要匹配具有多个部分的路由,如 /first/second/third,你应该用 *(0 个或多个)和 +(1 个或多个)将参数标记为可重复:

  1. const routes = [
  2. // /:chapters -> 匹配 /one, /one/two, /one/two/three, 等
  3. { path: '/:chapters+' },
  4. // /:chapters -> 匹配 /, /one, /one/two, /one/two/three, 等
  5. { path: '/:chapters*' },
  6. ]

这将为你提供一个参数数组,而不是一个字符串,并且在使用命名路由时也需要你传递一个数组:

  1. // 给定 { path: '/:chapters*', name: 'chapters' },
  2. router.resolve({ name: 'chapters', params: { chapters: [] } }).href
  3. // 产生 /
  4. router.resolve({ name: 'chapters', params: { chapters: ['a', 'b'] } }).href
  5. // 产生 /a/b
  6. // 给定 { path: '/:chapters+', name: 'chapters' },
  7. router.resolve({ name: 'chapters', params: { chapters: [] } }).href
  8. // 抛出错误,因为 `chapters` 为空

四、嵌套路由

4.1 用法

当我们在app文件里写了一个路由出口 route-view   作为最顶层的  它渲染顶层路由匹配的组件。同样的 一个被渲染的组件也可以包含自己嵌套的<router-view>;然后我们需要在路由中配置children。

  1. const routes = [
  2. {
  3. path: '/user/:id',
  4. component: User,
  5. children: [
  6. {
  7. // 当 /user/:id/profile 匹配成功
  8. // UserProfile 将被渲染到 User 的 <router-view> 内部
  9. path: 'profile',
  10. component: UserProfile,
  11. },
  12. {
  13. // 当 /user/:id/posts 匹配成功
  14. // UserPosts 将被渲染到 User 的 <router-view> 内部
  15. path: 'posts',
  16. component: UserPosts,
  17. },
  18. ],
  19. },
  20. ]

注意,以 / 开头的嵌套路径将被视为根路径。这允许你利用组件嵌套,而不必使用嵌套的 URL。

五、编程式导航

5.1 导航到不同的位置

在vue实例中  我们可以通过$router 访问路由实例  所以可以调用this.$router.push   这个方法可以跳转到你想去的路由 会向history栈添加一条新的记录 所以用户点击浏览器后退 会回到之前的URL。

  1. // 字符串路径
  2. router.push('/users/eduardo')
  3. // 带有路径的对象
  4. router.push({ path: '/users/eduardo' })
  5. // 命名的路由,并加上参数,让路由建立 url
  6. router.push({ name: 'user', params: { username: 'eduardo' } })
  7. // 带查询参数,结果是 /register?plan=private
  8. router.push({ path: '/register', query: { plan: 'private' } })
  9. // 带 hash,结果是 /about#team
  10. router.push({ path: '/about', hash: '#team' })

注意:如果提供了 pathparams 会被忽略,上述例子中的 query 并不属于这种情况。取而代之的是下面例子的做法,你需要提供路由的 name 或手写完整的带有参数的 path :

  1. const username = 'eduardo'
  2. // 我们可以手动建立 url,但我们必须自己处理编码
  3. router.push(`/user/${username}`) // -> /user/eduardo
  4. // 同样
  5. router.push({ path: `/user/${username}` }) // -> /user/eduardo
  6. // 如果可能的话,使用 `name` 和 `params` 从自动 URL 编码中获益
  7. router.push({ name: 'user', params: { username } }) // -> /user/eduardo
  8. // `params` 不能与 `path` 一起使用
  9. router.push({ path: '/user', params: { username } }) // -> /user

5.2 替换当前的位置  

和push 唯一不同的是  它在导航时不会向history 添加新纪录 只是替换了当前的URL而已

  1. router.push({ path: '/home', replace: true })
  2. // 相当于
  3. router.replace({ path: '/home' })

5.3 横跨历史

该方法采用一个整数作为参数,表示在历史堆栈中前进或后退多少步,类似于 window.history.go(n)

  1. // 向前移动一条记录,与 router.forward() 相同
  2. router.go(1)
  3. // 返回一条记录,与 router.back() 相同
  4. router.go(-1)
  5. // 前进 3 条记录
  6. router.go(3)
  7. // 如果没有那么多记录,静默失败
  8. router.go(-100)
  9. router.go(100)

六、命名路由

6.1 用法 

除了path之外  我们还可以给任何路由提供一个name 属性 

没有硬编码的URL  ;params的自动编码/解码;  防止你在URL中出现打字错误 ;绕过路径排序

  1. const routes = [
  2. {
  3. path: '/user/:username',
  4. name: 'user',
  5. component: User,
  6. },
  7. ]
  8. //要链接到一个命名的路由,可以向 router-link 组件的 to 属性传递一个对象
  9. <router-link :to="{ name: 'user', params: { username: 'erina' }}">
  10. User
  11. </router-link>
  12. //这个和push是一回事
  13. router.push({ name: 'user', params: { username: 'erina' } })

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/空白诗007/article/detail/804865
推荐阅读
相关标签
  

闽ICP备14008679号