Vue-Router介绍和使用

1. Vue Router介绍

Vue Router 是 Vue.js 官方的路由管理器。在 Vue.js 单页应用程序中实现客户端路由功能,通过将不同的 URL 映射到不同的组件,以实现页面之间的切换和导航。

Vue Router 的核心功能包括:

  1. 路由映射:Vue Router 允许您定义路由映射规则,将 URL 路径映射到 Vue 组件。通过使用路由映射,可以在 URL 改变时加载不同的组件,从而实现页面之间的切换。
  2. 嵌套路由:Vue Router 支持嵌套路由,允许您在父路由下定义子路由。这使得可以创建复杂的页面布局和嵌套组件结构,同时保持路由的层次性和可读性。
  3. 路由参数:可以在路由规则中定义参数,以捕获 URL 中的动态片段。这些参数可以作为路由组件的属性,用于动态地渲染组件内容。例如,可以定义一个带有商品ID参数的路由,以显示特定商品的详细信息。
  4. 路由导航:Vue Router 提供了导航守卫(Navigation Guards)功能,允许在路由切换前后执行相应的逻辑。可以在导航守卫中进行身份验证、权限检查或其他预处理逻辑,以决定是否允许用户访问或离开某个页面。
  5. 命名路由和命名视图:Vue Router 支持命名路由和命名视图,允许在路由规则和组件渲染时使用可读性更高的名称,而不是直接使用路径或组件名称。这可以提高代码的可维护性和可读性。

通过使用 Vue Router,可以实现单页应用程序的前端路由功能,构建交互式和流畅的用户界面。它与 Vue.js 框架无缝集成,并提供了丰富的路由管理功能,能够更轻松地管理应用程序的不同页面和导航逻辑。

官方地址:https://router.vuejs.org/zh/

2. 路由是什么

2.1. 计算机网络中的路由

路由是在计算机网络中,根据一定的规则和算法,将数据包从源节点传递到目标节点的过程。它是实现网络通信和数据传输的关键机制。

路由的工作原理是基于网络中的路由表(Routing Table)。路由表是一个存储在路由器或交换机中的数据结构,它记录了网络中各个目的地的可达路径和相关信息。根据路由表中的信息,路由器可以根据目标地址来选择下一个节点,并将数据包传递给适当的接口进行转发。

2.2. SPA是什么

SPA 是单页应用(Single-Page Application)的缩写,是一种 Web 应用程序的架构模式。在 SPA 中,整个应用程序只有一个 HTML 页面,该页面包含应用程序的骨架结构,而内容的变化和页面的切换是通过 JavaScript 动态地加载和更新的,而不是通过传统的多页应用中的页面刷新。

SPA 的特点包括:

  1. 单页面结构:SPA 只有一个初始的 HTML 页面,当用户与应用程序交互时,页面内容会动态地进行更新和切换,但浏览器不会重新加载整个页面。
  2. 前端路由:SPA 使用前端路由来管理页面的导航和切换。通过监听 URL 变化,SPA 可以根据不同的路由信息加载相应的组件或视图,实现页面间的无刷新切换。
  3. 异步加载:SPA 通过利用 AJAX、Fetch 或 WebSockets 等技术,可以异步地获取数据并更新页面内容,无需刷新整个页面。
  4. 更流畅的用户体验:由于 SPA 避免了页面的刷新,用户在与应用程序交互时会获得更快的响应速度和流畅的用户体验。
  5. 前后端分离:SPA 的前端与后端可以相对独立地开发和部署。前端负责处理用户界面和交互逻辑,而后端则负责提供数据接口和业务逻辑。

2.3. 前端路由

前端路由是一种在单页应用(SPA)中管理页面导航和视图切换的机制。前端路由通过在客户端内部维护一个路由器(router),根据 URL 的变化动态地加载不同的视图组件,实现页面的切换和导航,而无需重新加载整个页面。

简单的说就是:

  1. url与vue组件之间建立链接
  2. 用户点击了页面上的路由链接
  3. 前端路由把当前对应的组件渲染都浏览器中

3. 开始使用

3.1. 新建一个vue2项目

vue init webpack  "router-vue2"

可以在创建项目的时候直接安装router,但是这个为了学习使用就先不安装,等后面再安装

img

3.2. Vue Router安装

Vue-router当前最新版本为4

Vue-router4 对应 Vue3中使用

Vue-router3 对应 Vue2中使用

这里使用vue2所以安装vue-router@3, 安装命令

npm i vue-router@3

3.3. 路由配置和使用

3.3.1. 在src文件夹下创建router/index.js文件
// 该页面用于创建整个应用的路由管理者router
import VueRouter from "vue-router";

// 应用VueRouter
Vue.use(VueRouter)

// 创建路由对象
const router = new VueRouter({
  //路由规则
  routes: [{},]
})

// 暴露一个router
export default router
3.3.2. 在main.js中配置路由
import Vue from 'vue'
import App from './App'
import router from './router/index.js'

Vue.config.productionTip = false

/* eslint-disable no-new */
new Vue({
  render: h => h(App),
  // 挂载到vue实例中
  router
}).$mount('#app')
3.3.3. 新建两个页面

在src文件夹下新创建一个views文件夹,在views下创建Home.vue和My.vue

Home.vue

<template>
  <div>
    <h2>Home页面</h2>
  </div>
</template>

<script>
  export default {
  }
</script>

<style scoped>
  h2 {
    text-align: center;
  }
</style>

My.vue

<template>
  <div>
    <h2>My页面</h2>
  </div>
</template>

<script>
  export default {}
</script>

<style scoped>
  h2 {
    text-align: center;
  }
</style>
3.3.4. 在router/index.js中配置路由规则
// 该页面用于创建整个应用的路由管理者router
import Vue from "vue";
import VueRouter from "vue-router";

//引入路由组件
import Home from '../views/Home.vue'
import My from '../views/My.vue'

// 应用VueRouter
Vue.use(VueRouter)

// 创建路由对象
const router = new VueRouter({
  //路由规则
  routes: [
    //配置路由路径和路由组件
    {
      //这里的路径可自由定义
      path: '/Home',
      component: Home //要跳转到的组件  注意:这里不要加引号
    },
    {
      path: '/My',
      component: My //要跳转到的组件  注意:这里不要加引号
    },
  ]
})

// 暴露一个router
export default router
3.3.5. 在组件中使用路由

在App.vue中使用

<template>
  <div id="app">
    <!--    定义路由链接-->
    <router-link to="/Home">首页</router-link>
    <router-link to="/My">我的</router-link>

    <hr/>

    <!--    定义路由占位符(指定位置展示路由组件)-->
    <router-view/>
  </div>
</template>

<script>

  export default {
    name: 'App',
    components: {}
  }
</script>

<style>
  #app {
    font-family: 'Avenir', Helvetica, Arial, sans-serif;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    text-align: center;
    color: #2c3e50;
    margin-top: 60px;
  }
</style>
3.3.6. 页面展示

img

4. 常用方法

4.1. 路由重定向

路由重定向指的是:用户在访问一个地址的时候,强制用户跳转到另一个地址 ,从而展示特定的组件页面。

通过路由规则的redirect属性,可以很方便地设置路由的重定向

很多网站刚进入的时候默认显示首页内容,就可以用这个

// 该页面用于创建整个应用的路由管理者router
import Vue from "vue";
import VueRouter from "vue-router";

//引入路由组件
import Home from '../views/Home.vue'
import My from '../views/My.vue'

// 应用VueRouter
Vue.use(VueRouter)

// 创建路由对象
const router = new VueRouter({
  //路由规则
  routes: [
    {
      path: '/',
      redirect: '/Home' //重定向
    },
    //配置路由路径和路由组件
    {
      //这里的路径可自由定义
      path: '/Home',
      component: Home //要跳转到的组件  注意:这里不要加引号
    },
    {
      //这里的路径可自由定义
      path: '/My',
      component: My //要跳转到的组件  注意:这里不要加引号
    },
  ]
})

// 暴露一个router
export default router

4.2. 嵌套路由

新建两个TabA、TabB页面

TabA.vue

<template>
  <h2>TabA页面</h2>
</template>

TabB.vue

<template>
  <h2>TabB页面</h2>
</template>

router/index.js中配置嵌套路由

// 该页面用于创建整个应用的路由管理者router
import Vue from "vue";
import VueRouter from "vue-router";

//引入路由组件
import Home from '../views/Home.vue'
import My from '../views/My.vue'
import TabA from '../views/TabA.vue'
import TabB from '../views/TabB.vue'

// 应用VueRouter
Vue.use(VueRouter)

// 创建路由对象
const router = new VueRouter({
  //路由规则
  routes: [
    {
      path: '/',
      redirect: '/Home' //重定向
    },
    //配置路由路径和路由组件
    {
      //这里的路径可自由定义
      path: '/Home',
      component: Home, //要跳转到的组件  注意:这里不要加引号
      // 子路由(嵌套路由)
      children: [
        // 注意:子路由的 path 不需要加/
        {path: 'TabA', component: TabA},
        {path: 'TabB', component: TabB},
      ]
    },
    {
      //这里的路径可自由定义
      path: '/My',
      component: My //要跳转到的组件  注意:这里不要加引号
    },
  ]
})

// 暴露一个router
export default router

Home页面中使用

<template>
  <div>
    <h2>Home页面</h2>

    <router-link to="/Home/TabA">TabA</router-link>
    <router-link to="/Home/TabB">TabB</router-link>

    <hr/>

    <router-view/>

  </div>
</template>

<script>
  export default {
  }
</script>

<style scoped>
  h2 {
    text-align: center;
  }
</style>

页面展示

img

4.3. 路由传参

vue 路由传参的使用场景一般都是应用在父路由跳转到子路由时,携带参数跳转

有多种方式可以实现路由传参,以下是几种常见的方法:

4.3.1. params传参(路由路径参数Dynamic Route Matching)

在路由定义时,可以通过在路由路径中使用占位符来指定参数,并在路由组件中通过 $route.params 来获取传递的参数。

在 vue-router 中使用英文的冒号(:)来定义路由的参数项

TabA/:id 加参数id

// 该页面用于创建整个应用的路由管理者router
import Vue from "vue";
import VueRouter from "vue-router";

//引入路由组件
import Home from '../views/Home.vue'
import My from '../views/My.vue'
import TabA from '../views/TabA.vue'
import TabB from '../views/TabB.vue'

// 应用VueRouter
Vue.use(VueRouter)

// 创建路由对象
const router = new VueRouter({
  //路由规则
  routes: [
    {
      path: '/',
      redirect: '/Home' //重定向
    },
    //配置路由路径和路由组件
    {
      //这里的路径可自由定义
      path: '/Home',
      component: Home, //要跳转到的组件  注意:这里不要加引号
      // 子路由(嵌套路由)
      children: [
        // 注意:子路由的 path 不需要加/
        {path: 'TabA/:id', component: TabA},
        {path: 'TabB/:id', component: TabB},
      ]
    },
    {
      //这里的路径可自由定义
      path: '/My',
      component: My //要跳转到的组件  注意:这里不要加引号
    },
  ]
})

// 暴露一个router
export default router

Home中传参

<template>
  <div>
    <h2>Home页面</h2>

    <router-link to="/Home/TabA/1">TabA</router-link>
    <router-link to="/Home/TabB/2">TabB</router-link>

    <hr/>

    <router-view/>

  </div>
</template>

<script>
export default {
}
</script>

<style scoped>
h2 {
  text-align: center;
}
</style>

TabA中获取参数

<template>
  <h2>TabA页面,id为:{{this.$route.params.id}}</h2>
</template>

<script>
  export default {
  }
</script>

页面显示

img

4.3.2. query传参(查询参数Query Parameters)

可以通过在路由路径中使用查询参数来传递数据,并在路由组件中通过 $route.query 来获取传递的参数

Home中根据query传参

<template>
  <div>
    <h2>Home页面</h2>

    <router-link :to="{ path: '/Home/TabA', query: { id: '1' } }">TabA</router-link>
    <router-link :to="{ path: '/Home/TabB', query: { id: '2' } }">TabB</router-link>

    <hr/>

    <router-view/>

  </div>
</template>

<script>
export default {}
</script>

<style scoped>
h2 {
  text-align: center;
}
</style>

在TabA中接收传参

<template>
  <div>
    <h2>TabA页面,id为:{{ this.$route.query.id }}</h2>
  </div>
</template>

<script>
  export default {
  }
</script>

页面显示

img

4.3.3. meta传参(路由元信息Route Meta Fields)

可以在路由定义中添加元信息字段,用于传递自定义的参数或数据,并在路由组件中通过 $route.meta 来获取传递的数据

router/index.js中添加元信息字段(meta: {id: ‘123’})

// 该页面用于创建整个应用的路由管理者router
import Vue from "vue";
import VueRouter from "vue-router";

//引入路由组件
import Home from '../views/Home.vue'
import My from '../views/My.vue'
import TabA from '../views/TabA.vue'
import TabB from '../views/TabB.vue'

// 应用VueRouter
Vue.use(VueRouter)

// 创建路由对象
const router = new VueRouter({
  //路由规则
  routes: [
    {
      path: '/',
      redirect: '/Home' //重定向
    },
    //配置路由路径和路由组件
    {
      //这里的路径可自由定义
      path: '/Home',
      component: Home, //要跳转到的组件  注意:这里不要加引号
      // 子路由(嵌套路由)
      children: [
        // 注意:子路由的 path 不需要加/
        {path: 'TabA', component: TabA, meta: {id: '123'}},
        {path: 'TabB', component: TabB, meta: {id: '456'}},
      ]
    },
    {
      //这里的路径可自由定义
      path: '/My',
      component: My //要跳转到的组件  注意:这里不要加引号
    },
  ]
})

// 暴露一个router
export default router

Home页面

<template>
  <div>
    <h2>Home页面</h2>

    <router-link :to="{ path: '/Home/TabA' }">TabA</router-link>
    <router-link :to="{ path: '/Home/TabB' }">TabB</router-link>

    <hr/>

    <router-view/>

  </div>
</template>

<script>
  export default {}
</script>

<style scoped>
  h2 {
    text-align: center;
  }
</style>

TabA页面接收

<template>
  <div>
    <h2>TabA页面,id为:{{ this.$route.meta.id }}</h2>
  </div>
</template>

<script>
  export default {
  }
</script>

页面展示

img

5. 编程式导航和声明式导航

Vue Router提供了两种方式来进行导航:编程式导航和声明式导航

5.1. 编程式导航

编程式导航是通过在JavaScript代码中直接调用Vue Router的API来实现导航。你可以使用编程式导航来在组件中进行路由跳转、重定向或者前进/后退操作。以下是一些常见的编程式导航方法:

5.1.1. router.push(location):跳转到一个新的URL
<template>
  <div>
    <h2>Home页面</h2>
    <button @click="goTabA">跳转到TabA</button>
    <hr/>
    <router-view/>
  </div>
</template>

<script>
  export default {
    methods: {
      goTabA() {
        this.$router.push({ path: '/Home/TabA'});
      }
    }
  }
</script>

<style scoped>
  h2 {
    text-align: center;
  }
</style>

页面展示

img

5.1.2. router.replace(location):替换当前的URL,而不会在历史记录中创建新的记录。
<template>
  <div>
    <h2>Home页面</h2>
    <button @click="goTabA">跳转到TabA</button>
    <hr/>
    <router-view/>
  </div>
</template>

<script>
  export default {
    methods: {
      goTabA() {
        this.$router.replace({ path: '/Home/TabA'});
      }
    }
  }
</script>

<style scoped>
  h2 {
    text-align: center;
  }
</style>

页面展示

img

5.1.3. router.go(n):在历史记录中向前或向后移动多少步。

Home跳转到TabA

<template>
  <div>
    <h2>Home页面</h2>
    <button @click="goTabA">跳转到TabA</button>
    <hr/>
    <router-view/>
  </div>
</template>

<script>
  export default {
    methods: {
      goTabA() {
        this.$router.push({ path: '/Home/TabA'});
      }
    }
  }
</script>

<style scoped>
  h2 {
    text-align: center;
  }
</style>

TabA返回到Home

<template>
  <div>
    <h2>TabA页面</h2>
    <button @click="goBack">跳转到TabA</button>
  </div>
</template>

<script>
  export default {
    methods: {
      goBack() {
        this.$router.go(-1);
      }
    }
  }
</script>

页面展示

img

5.1.4. router.back():后退一步,等同于 router.go(-1)。
5.1.5. router.forward():前进一步,等同于 router.go(1)。

back、forward效果与go一样就不展示了

5.2. 声明式导航

声明式导航是通过在模板中使用Vue Router提供的指令来实现导航。你可以在模板中使用组件来生成导航链接,它会自动渲染为一个带有正确URL的超链接。当用户点击链接时,Vue Router会自动处理导航。

是一个用于生成路由链接的组件。它会自动渲染成一个 标签,并在点击时触发路由的导航。你可以通过指定 to 属性来设置要导航到的目标路由。

以下是一个使用声明式导航的示例:

<template>
  <div>
    <h2>Home页面</h2>
    <router-link to="/Home/TabA">TabA</router-link>
    <router-link to="/Home/TabB">TabB</router-link>
    <hr/>
    <router-view/>
  </div>
</template>

<script>
export default {
}
</script>

<style scoped>
h2 {
  text-align: center;
}
</style>

在上面的示例中,当用户点击"TabA"或"TabB"链接时,Vue Router会自动导航到相应的路由路径。

编程式导航和声明式导航在不同的场景下有不同的用途。

编程式导航通常用于在组件中通过JavaScript代码进行导航,例如在事件处理程序或生命周期钩子中进行动态导航,而声明式导航则更适合在模板中静态地生成导航链接。

6. 导航守卫

导航守卫是一组用于控制路由导航的钩子函数。这些钩子函数允许你在路由导航过程中进行拦截和控制,以实现诸如身份验证、权限检查、页面保护等功能。

Vue Router提供了三种类型的导航守卫钩子:

6.1. 全局守卫

在整个应用程序的路由导航过程中都会触发的钩子函数。包括以下钩子函数:

  1. beforeEach(to, from, next):在每个导航触发之前调用,可以用于进行全局的身份验证、权限检查等。
  2. beforeResolve(to, from, next):在每个导航被确认之前调用,可以用于处理异步路由组件的加载。
  3. afterEach(to, from):在每个导航成功完成后调用,可以用于执行一些全局的操作,如页面滚动、统计等。

beforeEach****的回调函数中接收 3 个形参

  • to:即将进入的路由Route对象;
  • from:即将离开的路由Route对象;
  • next是一个函数,调用next()表示放行, 允许这次路由跳转

next 函数的 3 种调用方式

实际案例中当用户访问后台系统主页时可能遇到如下情况

  • 当前用户拥有后台主页的访问权限,直接放行:next()
  • 当前用户没有后台主页的访问权限,强制其跳转到登录页面:next(‘/login’)
  • 当前用户没有后台主页的访问权限,不允许跳转到后台主页:next(false)
router.beforeEach((to, from, next) => {
    //to 要访问的路径
    //from 代表从哪个路径跳转而来
    // next 是函数,表示放行
    // next() 放行
    // next('/*') 强制跳转
    const user = window.sessionStorage.getItem('user')
    if (to.path === '/Login') {
        return next();
    }
    if (!user) {
        return next('/Login')
    }
    if (to.path === '/' && user) {
        return next('/home')
    }
    next()
})

6.2. 路由独享守卫

仅在特定路由配置中定义的钩子函数,可以在路由配置对象中使用beforeEnter来定义该钩子函数。

用法与全局守卫大同小异,独享路由守卫是没有后置路由守卫的

6.3. 组件内守卫

在路由组件内定义的钩子函数。包括以下钩子函数:

  1. beforeRouteEnter(to, from, next):在路由进入组件之前调用,可以在此钩子函数中访问组件实例之前的this上下文。
  2. beforeRouteUpdate(to, from, next):在当前路由复用组件时调用,但是参数发生变化时触发。
  3. beforeRouteLeave(to, from, next):在离开当前路由时调用,可以在此钩子函数中进行页面离开前的确认或者保存数据。

7. hash和history模式

路由有两种工作模式,分别是:hash 和 history,默认的就是 hash 的工作模式

7.1. hash模式

  1. url中# 就是代表 hash ,后面就是 hash 值
  2. 在hash模式下,URL中的哈希值(即#后面的部分)用于表示路由路径。例如,http://localhost:8080/#/Home/TabA
  3. 哈希值的变化不会触发浏览器向服务器发送请求,而是在前端进行处理。
  4. Vue Router通过监听hashchange事件来捕获哈希值的变化,并根据哈希值来进行路由的匹配和渲染。

7.2. history模式

history需要配置mode项:mode: ‘history’,

// 该页面用于创建整个应用的路由管理者router
import Vue from "vue";
import VueRouter from "vue-router";

//引入路由组件
import Home from '../views/Home.vue'
import My from '../views/My.vue'
import TabA from '../views/TabA.vue'
import TabB from '../views/TabB.vue'

// 应用VueRouter
Vue.use(VueRouter)

// 创建路由对象
const router = new VueRouter({
  mode: 'history',
  //路由规则
  routes: [
    {
      path: '/',
      redirect: '/Home' //重定向
    },
    //配置路由路径和路由组件
    {
      //这里的路径可自由定义
      path: '/Home',
      component: Home, //要跳转到的组件  注意:这里不要加引号
      // 子路由(嵌套路由)
      children: [
        // 注意:子路由的 path 不需要加/
        {path: 'TabA', component: TabA, meta: {id: '123'}},
        {path: 'TabB', component: TabB, meta: {id: '456'}},
      ]
    },
    {
      //这里的路径可自由定义
      path: '/My',
      component: My //要跳转到的组件  注意:这里不要加引号
    },
  ]
})

// 暴露一个router
export default router
  1. 在history模式下,URL中的路径表示实际的路由路径。例如,http://localhost:8080/Home/TabA
  2. history模式依赖于HTML5 History API,它允许前端控制浏览器的历史记录。
  3. 当路由切换时,history模式会使用pushState方法将新的URL添加到浏览器的历史记录中,而不会触发页面的刷新。
  4. 服务器端需要正确配置,以便在接收到这些URL时返回正确的页面内容。

7.3. hash和history模式区别

7.3.1. URL格式

hash模式:URL中包含一个哈希值(#),例如:http://localhost:8080/Home#/Home/TabA

history模式:URL中不包含哈希值,使用真实的URL路径,例如:http://localhost:8080/Home/TabA

7.3.2. 兼容性

hash模式:对于较低版本的浏览器,包括一些旧版的IE浏览器,都很好地支持hash模式。

history模式:需要服务器端的配置支持。在不支持HTML5 History API的环境中,会自动回退到hash模式。

7.3.3. URL美观性

hash模式:URL中的哈希值对于前端路由来说是一个片段标识符,不会发送到服务器端。因此,即使URL发生变化,页面也不会重新加载,但会触发前端路由的变化。

history模式:URL中的路径是真实的URL路径,可以直接发送到服务器端。当导航到一个新的URL时,页面会向服务器发送请求,并且服务器需要正确配置以返回对应的页面。

7.3.4. 历史记录

hash模式:每次路由切换时,哈希值会被添加到浏览器的历史记录中,因此可以通过浏览器的前进和后退按钮进行导航。

history模式:使用HTML5 History API,路由切换时会修改浏览器的URL,但不会添加额外的历史记录。因此,通过浏览器的前进和后退按钮进行导航会触发真实的页面加载。

  • 29
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值