vue-路由

路由

用 Vue.js + Vue Router 创建单页应用,感觉很自然:使用 Vue.js ,我们已经可以通过组合组件来组成应用程序,当你要把 Vue Router 添加进来,我们需要做的是,将组件 (components) 映射到路由 (routes),然后告诉 Vue Router 在哪里渲染它们。

起步

我们来看一下脚手架的给我们大家的路由实例:

//导入创建路由对象方法和hash 模式路径方法
import { createRouter, createWebHashHistory } from 'vue-router
//创建路由表
const routes = [
{
    path: '/',
    name: 'Home',
    component: () => import('../views/Home.vue'),
},
{
    path: '/about/:id',
    name: 'About',
    component: () => import('../views/About.vue')
},
]
//创建路由对象
const router = createRouter({
  history: createWebHashHistory(),//hash模式路径
  routes//路由表
})
//导出路由对象
export default router

如何使用路由

//to属性指定路由路径
<router-link to="/">Home</router-link> |
<router-link to="/about">About</router-link>
//router-view为路由视图
<router-view/>

动态路由匹配(传参)

我们经常需要把某种模式匹配到的所有路由,全都映射到同个组件。例如,我们有一个 User 组件,对于所有 ID 各不相同的用户,都要使用这个组件来渲染。那么,我们可以在 vue-router 的路由路径中使用“动态路径参数”(dynamic segment) 来达到这个效果:

//路由表
{
    path: '/about/:id/:name',
    name: 'About',
    component: () => import('../views/About.vue'),
 }
//App.vue
<router-link to="/about/001/zhangsan">About</router-link>

一个“路径参数”使用冒号 : 标记。当匹配到一个路由时,参数值会被设置到 this.$route.params,可以在每个组件内使用。于是,我们可以更新 User 的模板,输出当前用户的 ID:

//About.vue
{{$route.params.id}}

响应路由参数的变化

提醒一下,当使用路由参数时,例如从 /user/foo 导航到 /user/bar,原来的组件实例会被复用。因为两个路由都渲染同个组件,比起销毁再创建,复用则显得更加高效。不过,这也意味着组件的生命周期钩子不会再被调用。

复用组件时,想对路由参数的变化作出响应的话,你可以简单地 watch (监测变化) $route 对象

//Home.vue
watch:{
    $route(to, from) {
      console.log(to)
      console.log(from)
    }
 }

匹配所有路径

常规参数只会匹配被 / 分隔的 URL 片段中的字符。如果想匹配任意路径,我们可以使用通配符 (*):

{     
// 匹配所有路径  vue2使用*   vue3使用/:pathMatch(.*)    
path:"*",//vue2
path: "/:pathMatch(.*)", 
path: '/stu:pathMatch(.*)',//可以以什么开头    
name: "404",     
component: () => import('../views/404.vue')  
}
 {
    path: '/:pathMatch(.*)',//vue3
    name: '404',
    component: () => import( '../views/404.vue')//这是另外一种导入路由所需模块的方式
  }

 

当使用一个通配符时,$route.params 内会自动添加一个名为 pathMatch 参数。它包含了 URL 通过通配符被匹配的部分:

//404.vue
{{$route.params.pathMatch}}
//返回地址名

匹配优先级

有时候,同一个路径可以匹配多个路由,此时,匹配的优先级就按照路由的定义顺序:路由定义得越早,优先级就越高。

嵌套路由

在项目中,我们的路由可能会更加复杂,例如About路由中还需要嵌套子路由,分别显示homeA和homeB两个子模块,我们就需要为About路由添加children属性,并创建About模块的路由视图:

{
    path: '/',//路径
    name: 'Home',//可以不写
    component: Home, //模块
    // components:{
    //   default:Home,
    //   a:() => import( '../views/HomeA.vue'),
    //   b:() => import( '../views/HomeB.vue'),
    // },
   children:[
    {path: '/homeA',
    component: () => import( '../views/HomeA.vue')},
    {path: '/homeB',
    component: () => import( '../views/HomeB.vue')}
   ]

  },

编程式的导航

除了使用 <router-link> 创建 a 标签来定义导航链接,我们还可以借助 router 的实例方法,通过编写代码来实现。

注意:在 Vue 实例内部,你可以通过 $router 访问路由实例。因此你可以调用 this.$router.push。

router.replace()

跟 router.push 很像,唯一的不同就是,它不会向 history 添加新记录,而是跟它的方法名一样 —— 替换掉当前的 history 记录。

router.go(n)

这个方法的参数是一个整数,意思是在 history 记录中向前或者后退多少步,类似 window.history.go(n)。

 methods:{
    gohome(){
      this.$router.push('/')//字符串模式 只能是路径
      this.$router.replace('/')//不会添加新的历史记录,替换掉现有记录
       this.$router.go(1)//前进(1)和后退(-1)和刷新(0)
      this.$router.push({path:'/about/001/zhangsan'})//对象模式
       this.$router.push({name:'Home'})//对象模式
      //path模式下params会被忽略
      this.$router.push({name: 'About', params: { id:1,name:'zhangsan'}})
    }
  },

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

const userId = '123'
router.push({ name: 'user', params: { userId }}) // -> /user/123
router.push({ path: `/user/${userId}` }) // -> /user/123
// 这里的 params 不生效
router.push({ path: '/user', params: { userId }}) // -> /user

命名路由

有时候,通过一个名称来标识一个路由显得更方便一些,特别是在链接一个路由,或者是执行一些跳转的时候。你可以在创建 Router 实例的时候,在 routes 配置中给某个路由设置名称。

<router-link :to="{ name: 'user', params: { userId: 123 }}">User</router-link>

命名视图

有时候想同时 (同级) 展示多个视图,而不是嵌套展示,例如创建一个布局,有 sidebar (侧导航) 和 main (主内容) 两个视图,这个时候命名视图就派上用场了。你可以在界面中拥有多个单独命名的视图,而不是只有一个单独的出口。如果 router-view 没有设置名字,那么默认为 default。

//APP.vue
<router-view class="view one"></router-view>
<router-view class="view two" name="a"></router-view>
<router-view class="view three" name="b"></router-view>
//路由表
components: {
    default: Home,
    a: Bar,
    b: Baz
}

重定向

重定向也是通过 routes 配置来完成,下面例子是从 /a 重定向到 /b:

const router = new VueRouter({
  routes: [
    { path: '/a', redirect: '/b' }
  ]
})

重定向的目标也可以是一个命名的路由:

const router = new VueRouter({
  routes: [
    { path: '/a', redirect: { name: 'foo' }}
  ]
})

别名

“重定向”的意思是,当用户访问 /a时,URL 将会被替换成 /b,然后匹配路由为 /b,那么“别名”又是什么呢?

/a 的别名是 /b,意味着,当用户访问 /b 时,URL 会保持为 /b,但是路由匹配则为 /a,就像用户访问 /a 一样。alias: '/b'

const router = new VueRouter({
  routes: [
    { path: '/a', component: A, alias: '/b' }
  ]
})

路由组件传参

在组件中使用 $route 会使之与其对应路由形成高度耦合,从而使组件只能在某些特定的 URL 上使用,限制了其灵活性。

取代与 $route 的耦合

<div>User {{ $route.params.id }}</div>'

通过 props 解耦

//实例
props: ['id']
//路由表
{ path: '/user/:id', component: User, props: true//开启props传参模式 
},

布尔模式

如果 props 被设置为 true,route.params 将会被设置为组件属性

对象模式

如果 props 是一个对象,它会被按原样设置为组件属性。当 props 是静态的时候有用。

props: { id: 456 }

函数模式

你可以创建一个函数返回 props。这样你便可以将参数转换成另一种类型,将静态值与基于路由的值结合等等。

props:route => ({ id: route.params.id })//在这里你可以选择对接收到的参数做一些处理
 props:route => ({ id:'$'+ route.params.id }),//函数模式

History 模式

vue-router 默认 hash 模式 —— 使用 URL 的 hash 来模拟一个完整的 URL,于是当 URL 改变时,页面不会重新加载。

如果不想要很丑的 hash,我们可以用路由的 history 模式

//History 模式(不带#)
import { createRouter, createWebHistory } from 'vue-router'
//Hash 模式(带#)
import { createRouter, createWebHashHistory } from 'vue-router'

全局前置守卫

你可以使用 router.beforeEach 注册一个全局前置守卫

//以判断用户是否登录为例
router.beforeEach((to, from, next) => {
   if(cookie.get('login'))
   next()
   else{
    if (to.path !== "/login") {
      next({ path: "/login" });
    } else {
      next();
    }
   }   
})

当一个导航触发时,全局前置守卫按照创建顺序调用。守卫是异步解析执行,此时导航在所有守卫 resolve 完之前一直处于 等待中。

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

to: Route: 即将要进入的目标 路由对象

from: Route: 当前导航正要离开的路由

当添加了某种守卫,如果不进行next方法,那么守卫会将路由拦截

next: Function: 一定要调用该方法来 resolve 这个钩子。执行效果依赖 next 方法的调用参数。

next(): 进行管道中的下一个钩子。如果全部钩子执行完了,则导航的状态就是 confirmed (确认的)。

next(false): 中断当前的导航。如果浏览器的 URL 改变了 (可能是用户手动或者浏览器后退按钮),那么 URL 地址会重置到 from 路由对应的地址。

next('/') 或者 next({ path: '/' }): 跳转到一个不同的地址。当前的导航被中断,然后进行一个新的导航。你可以向 next 传递任意位置对象,且允许设置诸如 replace: true、name: 'home' 之类的选项以及任何用在 router-link 的 to prop 或 router.push 中的选项。

next(error): (2.4.0+) 如果传入 next 的参数是一个 Error 实例,则导航会被终止且该错误会被传递给 router.onError() 注册过的回调。

全局解析守卫(组件)

在 2.5.0+ 你可以用 router.beforeResolve 注册一个全局守卫。这和 router.beforeEach 类似,区别是在导航被确认之前,同时在所有组件内守卫和异步路由组件被解析之后,解析守卫就被调用。

全局后置钩子

你也可以注册全局后置钩子,然而和守卫不同的是,这些钩子不会接受 next 函数也不会改变导航本身,导航被确认后,全局后置钩子被调用:

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

路由独享的守卫

你可以在路由配置上直接定义 beforeEnter 守卫,在全局前置守卫触发后, beforeEnter 守卫被调用:

const router = new VueRouter({
  routes: [
    {
      path: '/foo',
      component: Foo,
      beforeEnter: (to, from, next) => {
        // ...
      }
    }
  ]
})

组件内的守卫

最后,你可以在路由组件内直接定义以下路由导航守卫:

beforeRouteEnter(to, from, next) {
    // 在渲染该组件的对应路由被 confirm 前调用
    // 不!能!获取组件实例 `this`
    // 因为当守卫执行前,组件实例还没被创建
  },
  beforeRouteUpdate(to, from, next) {
    // 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
    // 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
    // 可以访问组件实例 `this`
  },
  beforeRouteLeave(to, from, next) {
    // 导航离开该组件的对应路由时调用
    // 可以访问组件实例 `this`
  }

路由元信息

定义路由的时候可以配置 meta 字段:

一个路由匹配到的所有路由记录会暴露为 $route 对象 (还有在导航守卫中的路由对象) 的 $route.matched 数组。因此,我们需要遍历 $route.matched 来检查路由记录中的 meta 字段。

//路由表
meta: { requiresAuth: true }
//About.vue
{{$route.matched[0].meta}}

  • 11
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue Router 是 Vue.js 官方的路由管理器,用于实现前端路由跳转。要进行路由跳转,你需要完成以下几个步骤: 1. 首先,确保你的项目中已经安装了 Vue Router。可以通过 npm 或 yarn 进行安装: ```bash npm install vue-router ``` 或 ```bash yarn add vue-router ``` 2. 在你的 Vue 项目的入口文件(一般是 `main.js`)中引入 Vue Router,并使用它: ```javascript import Vue from 'vue' import VueRouter from 'vue-router' // 导入你的路由配置文件 import routes from './routes' Vue.use(VueRouter) const router = new VueRouter({ mode: 'history', // 可选值为 'hash' 或 'history',默认为 'hash' routes // 路由配置 }) new Vue({ router, // 注入路由实例 render: h => h(App) }).$mount('#app') ``` 3. 创建一个路由配置文件(例如 `routes.js`),在该文件中定义路由的映射关系: ```javascript import Home from './views/Home.vue' import About from './views/About.vue' const routes = [ { path: '/', name: 'home', component: Home }, { path: '/about', name: 'about', component: About } ] export default routes ``` 4. 在你的 Vue 组件中使用 `<router-link>` 标签或 `$router` 对象进行路由跳转。下面是几个常用的示例: - 使用 `<router-link>` 标签实现路由跳转: ```html <router-link to="/">Home</router-link> <router-link to="/about">About</router-link> ``` - 使用 `$router` 对象编程式地进行路由跳转: ```javascript // 在某个方法中跳转到指定路由 this.$router.push('/') // 跳转到根路径 this.$router.push('/about') // 跳转到 /about 路径 // 在某个方法中通过路由名称跳转 this.$router.push({ name: 'home' }) // 跳转到名称为 home 的路由 ``` 这样,你就可以通过 Vue Router 实现路由跳转了。请注意,以上只是一个简单的示例,你可以根据实际需要配置更多高级功能,例如路由参数、嵌套路由等。详情请参考 Vue Router 的官方文档。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值