Vue路由router详解

目录
  • 模块化的方式使用路由插件
  • 使用路由
    • 声明式导航
    • 编程式导航
  • 动态路由匹配
  • 通配符匹配路径
  • 查询参数query
  • 响应路由参数的变化
  • 命名路由,路由别名,重定向
  • 嵌套路由
  • 命名视图
  • 导航守卫
    • (1)全局守卫
    • (2)路由独享守卫
    • (3)组件内守卫
    • 导航解析的流程
  • 总结

模块化的方式使用路由插件

(1)安装

npm install vue-router

(2)构建文件目录

在src目录下创建一个router文件夹,然后创建一个index.js

(3)这里我们通过模块化的方式进行创建路由,方便代码的管理,这里只是对路插件进行了注册,然后创建好路由对象。通过export default 关键字将创建好的路由对象暴露出去。

//index.js
import VueRouter from 'vue-router'
import Vue from 'vue'
import Home from "../views/Home";
Vue.use(VueRouter)//注册路由插件
export default  new VueRouter({
    routes:[{
        path:'/',
        component:Home
    }]
})

(4)在入口文件main.js引入创建好的路由对象,并且把他挂载到Vue实例中。

//main.js
import Vue from 'vue'
import App from './App.vue'
import store from '@/store'
import router from '@/router'//这里就是引入了我们创建好的路由对象。模块化的编程思维
Vue.config.productionTip = false
Vue.prototype.bus = new Vue()
new Vue({
  store,
  router,
  render: h => h(App),
}).$mount('#app')

使用路由

声明式导航

可以理解成,通过标签进行跳转

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

定义路由规则

 {
        path:'/',
        component:Home
        name:home
    }

(1)router-link导航标签to属性使用字符串方式

 <router-link to="/">go to home</router-link>

(2)router-link导航标签to使用对象的方式

使用路径进行匹配

 <router-link :to="{path:'/'}">go to home</router-link>

router-link导航标签to属性使用对象的方式并且使用路由名称进行匹配

 <router-link :to="{name:'home'}">go to home</router-link>

编程式导航

可以理解成JS进行跳转

编程式导航:router.push(...)

下面的例子包含了动态路由匹配和query查询参数的知识,不清楚的可以先看了这两者的内容再回来看此处的内容。

// 字符串
router.push('home')
// 对象
router.push({ path: 'home' })
// 命名的路由
router.push({ name: 'user', params: { userId: '123' }})
// 带查询参数,变成 /register?plan=private
router.push({ path: 'register', query: { plan: 'private' }})

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

动态路由匹配

定义路由规则

 {
        path:'/user/:id',
        component:User
        name:user
    }
 <router-link to="/user/01">go to home</router-link>
 <router-link :to="{path:'/user/01'}">go to home</router-link>
 <router-link :to="{name:'/user',params={id:'01'}}">go to home</router-link>

通过如上的方式进行定义,可以通过$route.params.id 获动态路由参数:id值为'01‘

注意:

当使用对象的方式进行匹配时候,不能通过path和params的方式。只能通过name和params的方式

如下方式,不能匹配到路由规则{path:'/user/:id'} ,如下表述只能被理解成'/user',

即使通过*通配符匹配到该路由,params也不会被传递过去,因为要有path这个属性就不会去解析params的属性了。

{
  // 会匹配所有路径
  path: '*'
}
{
  // 会匹配以 `/user-` 开头的任意路径
  path: '/user-*'
}

通配符匹配路径

我们通常使用*捕获其他意外的路径,进行个兜底的处理,通常将其导航到404错误页面。

<router-link to=“/user?name=zhangsan">...</router-link>
<router-link :to="{path:'/user?zhangsan'}">...</router-link>
<router-link :to="{path:'/user',query:{name:'zhangsan'}}">...</router-link>
<router-link :to="{name:'user',query:{name:'zhangsan'}}">...</router-link>

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

查询参数query

<router-link to=“/user?name=zhangsan">...</router-link>
<router-link :to="{path:'/user?zhangsan'}">...</router-link>
<router-link :to="{path:'/user',query:{name:'zhangsan'}}">...</router-link>
<router-link :to="{name:'user',query:{name:'zhangsan'}}">...</router-link>

查询参数不想动态路由参数匹配那样,就算使用了path,依然可以使用query进行传参;

以上query传递过来的参数可以通过this.$route.query.name进行获取。

响应路由参数的变化

如果路由从/user/01导航到/user/02,原来的组件实例会被复用。因为有两个路由都渲染同一个组件,这意味着组件的生命周期钩子不会被再次调用。因此需要通过其他方式进行监听参数的变化来做出响应。

(1)通过watch进行监听

const User = {
  template: '...',
  watch: {
    $route(to, from) {
      // 对路由变化作出响应...
    }
  }
}

(2)通过导航守卫进行监听

const User = {
  template: '...',
  beforeRouteUpdate(to, from, next) {
    // react to route changes...
    // don't forget to call next()
  }
}

命名路由,路由别名,重定向

特别地我把这三者的概念放在一起来阐述,是为了更好的去区分他们之间的区别。这些内容都是在路由规则去配置的

{
        path: '/pageOne',
        component:PageOne,
        alias:"/firstPage",
        name:"pageOne",
        redirect:{name:'pageTwo'}
    },
    {
        path: '/pageTwo',
        component:PageTwo,
        name:'pageTwo'
    }

(1)命名路由:可以理解成给这个路由取个名字

即使通过name属性给路由取一个名字

routes: [
    {
      path: '/user/:userId',
      name: 'user',
      component: User
    }
  ]

(2)路由别名:可以理解成这个路由的第二个名字。

例如:/a的别名是/b,当用户访问/b的时候,URL会保持/b但是路由匹配到的内容则为/a,也就是知识URL内容显示/b内容实则是/a

注意了:这里别名要使用路径的方式去表述,而不是跟命名路由那样直接写名字哦~

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

(3)重定向:可以理解为访问/a的时候直接跳转到/b

重定向的表述有三种形式:

  • 字符串
const router = new VueRouter({
  routes: [
    { path: '/a', redirect: '/b' }
  ]
})
  • 对象
const router = new VueRouter({
  routes: [
    { path: '/a', redirect: { name: 'foo' }}
  ]
})
  • 方法
const router = new VueRouter({
  routes: [
    { path: '/a', redirect: to => {
      // 方法接收 目标路由 作为参数
      // return 重定向的 字符串路径/路径对象
    }}
  ]
})

嵌套路由

嵌套路由可以这么理解,所匹配的路由渲染出来的组件中包含路由组件,'/user'当我们匹配到一个路由渲染出一个组件User,但是如果想继续在User组件的<router-view ></router-view>继续匹配。则我们要通过/user/childRouteName进一步匹配。"childRouteName"就是我们路由规则children中对应的path的值啦。

 {
      path: '/user',
      component: User,
      children: [
        {
          // 当 /user//profile 匹配成功,
          // UserProfile 会被渲染在 User 的 <router-view> 中
          path: 'profile',
          component: UserProfile
        },
        {
          // 当 /user//posts 匹配成功
          // UserPosts 会被渲染在 User 的 <router-view> 中
          path: 'posts',
          component: UserPosts
        }
      ]
    }

APP.Vue中

<div id="app">
  <router-view></router-view>
</div>

User组件中

const User = {
  template: `
    <div class="user">
      <span>User组件</span>
      <router-view></router-view>
    </div>
  `
}

注意:

定义了嵌套路由,即定义了children的情况下,必须是完整的路由才可以匹配正确。也就是 当 /user/profile匹配成功,但是/user这样是无法匹配成功的。

命名视图

当一个组件上同时渲染多个视图,注意是同级展示多个视图,而不是嵌套展示。那此时就可以通过命名视图来解决这个问题。
路由规则定义

{
        path:"/namingRoute",
        components:{//注意此处components是带's'结尾的,之前单个的时候是不带的。
            default:Home,
            one:PageOne,
            two:PageTwo
        }
    }

组件定义

 	<router-view></router-view>//渲染default对应的组件
    <router-view name="one"></router-view>//渲染one对应的组件
    <router-view name="two"></router-view>//渲染two对应的组件

当URL为:/namingRoute的时候 匹配到该路由,则会按照对应的router-view视图组件进行渲染。

导航守卫

(1)全局守卫

可以理解成通过全局router实例对象router进行定义的守卫。

  • route.beforeEach(全局前置守卫)

使用方式:

beforeEach((to,from,next)=>{
	//...
})
  • router.beforeResolve(全局解析守卫)

在所有组件内守卫和异步路由组件被解析之后,解析守卫就被调用

使用方式:

router.beforeResolve((to, from, next) => {
  // ...
})
  • router.afterEach (全局后置钩子)

钩子不会接受 next 函数也不会改变导航本身:

使用方式:

router.afterEach((to, from) => {
  // ...
})
使用的位置:通常在router文件夹下的index.js
const router = new VueRouter({ ... })
//全局前置守卫
router.beforeEach((to, from, next) => {
  // ...
})
//全局解析守卫
router.beforeResolve((to, from, next) => {
  // ...
})
//全局后置钩子
router.afterEach((to, from) => {
  // ...
})

(2)路由独享守卫

可以理解成在路由规则上定义的守卫

  • beforeEnter

(3)组件内守卫

可以理解成在组件内定义的守卫

  • beforeRouteEnter

还没有创建组件实例,在该路由被confirm前调用。

const User = {
  template: `...`,
  beforeRouteEnter(to, from, next) {
    // 在渲染该组件的对应路由被 confirm 前调用
    // 不!能!获取组件实例 `this`
    // 因为当守卫执行前,组件实例还没被创建
  }
}

注意:

该守卫不能直接使用this访问vue实例对象,因为此时组件实例还没有被创建。但是可以通过给next方法传递回调来方位组件的实例。

给next()传递回调,仅在beforeRouteEnter使用有效!!!

beforeRouteEnter (to, from, next) {
  next(vm => {
    // 通过 `vm` 访问组件实例
  })
}
  • beforeRouteUpdate (2.2 新增)

在路由改变且该组件被服用时调用

const User = {
  template: `...`,
  beforeRouteUpdate(to, from, next) {
    // 在当前路由改变,但是该组件被复用时调用
    // 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
    // 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
    // 可以访问组件实例 `this`
  }
}
  • beforeRouteLeave

在导航离开该组件对应的路由时调用

const User = {
  template: `...`,
  beforeRouteLeave(to, from, next) {
    // 导航离开该组件的对应路由时调用
    // 可以访问组件实例 `this`
  }
}

导航解析的流程

正常首次访问路由的执行顺序

  • beforeEach 全局的路由前置守卫
  • beforeEnter 独享路由守卫
  • beforeRouteEnter 组件路由守卫
  • beforeResolve 全局路由解析守卫
  • afterEach 全局路由后置钩子
  • Dom渲染
  • 调用beforeRouteEnter 组件路由守卫中传递给next的回调函数。并且把创建号的组件实例作为回调函数的参数传入。

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注我们的更多内容!

(0)

相关推荐

  • 详解VueRouter进阶之导航钩子和路由元信息

    导航钩子 vue-router 提供的导航钩子主要用来拦截导航,让它完成跳转或取消.有多种方式可以在路由导航发生时执行钩子:全局的, 单个路由独享的, 或者组件级的. 全局钩子 你可以使用 router.beforeEach 注册一个全局的 before 钩子: const router = new VueRouter({ ... }) router.beforeEach((to, from, next) => { // ... }) 当一个导航触发时,全局的 before 钩子按照创建顺序调用

  • 详解VueRouter 路由

    目录 vue router 1.认识路由的概念 1.1.何为路由 1.2.后端路由阶段 1.3.前端路由阶段 1.4.前端渲染和后端渲染? 2.前端路由的规则 2.1.URL的hash 方式 2.2.HTML5的history模式 3.route-view的基础 3.1 认识vue-router 3.2.安装和使用vue-router 3.3.路由的默认路径 3.4.HTML5的history模式 3.5.router-link补充 3.6.路由代码跳转 3.7.动态路由 4.路由的懒加载 4.

  • Vue3使用路由VueRouter4的简单示例

    路由 vue-router4保持了大部分API不变,我们只关注变化部分即可. 安装 yarn add vue-router@4 引入 cdn <script src="https://cdn.bootcdn.net/ajax/libs/vue-router/4.0.6/vue-router.cjs.js"></script> 使用 router.js import { createRouter, createWebHistory } from "vue

  • 使用VueRouter的addRoutes方法实现动态添加用户的权限路由

    最近做vue 单页项目涉及到多角色用户权限问题,不同的角色用户拥有不同的功能权限, 不同的功能权限对应的不同的页面 git: https://github.com/pch1024/dynamicRouter 举个例子: 角色A =>功能1 =>功能2 =>功能3 角色B =>功能1 =>功能4 =>功能5 第1步 定义默认路由和动态路由 //动态路由(所有角色的都在这里,我们都做好组件页面了所以我们一定有这个,防君子不防小人) export const dynamicR

  • Vue路由router详解

    目录 模块化的方式使用路由插件 使用路由 声明式导航 编程式导航 动态路由匹配 通配符匹配路径 查询参数query 响应路由参数的变化 命名路由,路由别名,重定向 嵌套路由 命名视图 导航守卫 (1)全局守卫 (2)路由独享守卫 (3)组件内守卫 导航解析的流程 总结 模块化的方式使用路由插件 (1)安装 npm install vue-router (2)构建文件目录 在src目录下创建一个router文件夹,然后创建一个index.js (3)这里我们通过模块化的方式进行创建路由,方便代码的

  • react-router-domV6嵌套路由实现详解

    目录 V6新特性 <Route>的属性变更component/render->element <Link/>使用变动 <Redirect/> 替换为 <Navigate/> <Switch/> 重命名为 <Routes/> 用useNavigate代替useHistory 依赖包大小从20kb减少到8kb,整体体积减少 新钩子useRoutes代替react-router-config 新标签:<Outlet/> V

  • node创建Vue项目步骤详解

    vue的安装 Vue.js不支持IE8及以下版本.因为Vue.js使用了ECMAScript5特性,IE8显然不能模拟. Vue.js支持所有兼容ECMAScript5的浏览器. 在用Vue.js构建大型应用时,推荐使用npm安装,npm能很好的和webpack等打包工具配合使用. 首先Vue的安装依赖于node.js,要保证你的计算机上已经安装过node.js. 如何查看node是否安装或者node版本呢? 进入cmd,输入命令 node -v,回车查看.node最好使用新一些的版本,否则后续

  • 基于gin的golang web开发:路由示例详解

    Gin是一个用Golang编写的HTTP网络框架.它的特点是类似于Martini的API,性能更好.在golang web开发领域是一个非常热门的web框架. 启动一个Gin web服务器 使用下面的命令安装Gin go get -u github.com/gin-gonic/gin 在代码里添加依赖 import "github.com/gin-gonic/gin" 快速启动一个Gin服务器的代码如下 package main import "github.com/gin-

  • Vue中 Vue.prototype使用详解

    目录 1. 基本示例 2. 为实例prototype设置作用域 3. 注册和使用全局变量 4. 原型方法的上下文 5. 应用示例 5.1 引入 axios Vue.prototype.Vue.component和Vue.use区别 1.Vue.prototype 2.vue.component 3.Vue.use 我们可能会在很多组件里用到数据/实用工具,但是不想污染全局作用域.这种情况下,可以通过在原型上定义它们使其在每个 Vue 的实例中可用. 1. 基本示例 在main.js中添加一个变量

  • golang微服务框架基础Gin基本路由使用详解

    目录 概述 1. 基本路由 2. 路由参数 获取URL路径全部参数 获取URL路径单个参数 获取URL中指定的参数 获取指定默认值的参数的 概述 路由是自定义url地址执行指定的函数,良好的路由定义可以对seo起到很好的效果. 1. 基本路由 gin框架封装了http库,提供了 GET.POST.PUT.DELETE.PATCH.HEAD.OPTIONS 这些http请求方式. 使用 router.method() 来绑定路由 func (group *RouterGroup) METHOD(r

  • react-router-domV6版本的路由和嵌套路由写法详解

    目录 1-单级路由 2-嵌套路由(about路径进行嵌套) ReactRouterv6使用路由嵌套和重定向 1 - 单级路由 <NavLink to="/home">Home</NavLink> <NavLink to="/about">about</NavLink> <Routes>   <Route path='/home' element={<Home/>}/>   <R

  • react实现移动端二级路由嵌套详解

    页面效果展示 功能需求 根据下面不同的标题切换不同的页面,请求接口数据,渲染页面数据,点击左侧数据,进入详情页面,在右侧图片中点击返回返回左面页面 实现代码 我们用到了react中的router,首先我们要下载react的路由,命令是 react-router-dom@5 --save 路由5版本跟6版本使用语法上略有区别,现在使用较多的是5版本 我们首先在index.js文件中引入react路由,然后进行路由跳转 import { default as React } from 'react'

  • [译]ASP.NET Core 2.0 路由引擎详解

    本文介绍了ASP.NET Core 2.0 路由引擎详解,分享给大家,具体如下: 问题 ASP.NET Core 2.0的路由引擎是如何工作的? 答案 创建一个空项目,为Startup类添加MVC服务和请求中间件: public void ConfigureServices(IServiceCollection services) { services.AddMvc(); } public void Configure(IApplicationBuilder app, IHostingEnvir

  • Vue自定义事件(详解)

    前面的话 父组件使用props传递数据给子组件,子组件怎么跟父组件通信呢?这时,Vue的自定义事件就派上用场了.本文将详细介绍Vue自定义事件 事件绑定 每个 Vue 实例都实现了事件接口 (Events interface),即 使用 $on(eventName) 监听事件 使用 $emit(eventName) 触发事件 [注意]Vue 的事件系统分离自浏览器的EventTarget API.尽管它们的运行类似,但是 $on 和 $emit 不是addEventListener 和 disp

随机推荐