前端开发简说Vue-router路由

Posted 李猫er

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了前端开发简说Vue-router路由相关的知识,希望对你有一定的参考价值。

1、认识路由

SPA 和 Vue-router 路由

是针对 SPA(single page web application)单页面应用,根据 URL 地址中不同的 #值,表示不同的访问状态,通过 Ajax 异步获取数据,然后进行页面渲染,用户的感觉象真的更换了页面一样。

SPA 的优点是:

  • 良好的交互体验:页面只是局部内容被刷新,不需要重新刷新整个页面,页面显示流畅。
  • 前后端工作分离模式:服务器只提供数据,不用管展示逻辑和页面合成,减轻服务器压力。

Vue-router 路由

vue-router 是基于 Vue CLI 应用程序使用,是Vue.js官方的路由插件,适合用于构建单页面应用。
安装完成后选择 URL 路由模式:
history 模式:类似于普通的 url,但是页面刷新时可能会有问题。
hash 模式:使用 "#"号来分隔 URL,这种比较丑。

2、vue-router基本使用

安装vue-router:

npm install vue-router --save

安装成功后自动会在src目录下生成一个router文件夹,里面包含一个index.js

创建router实例

在router中的index.js:

  1. 导入路由对象,并调用Vue.use(VueRouter)
import Vue from 'vue'
import Router from 'vue-router'
import Login from '../views/Login'

// 1.注入路由
Vue.use(Router)

// 2.定义路由
const routes = [
  {
    path: '/',
    name: 'Login',
    component: 'Login'
  }
]

// 3. 创建路由实例
const router = new Router({
  routes
})

// 4. 导出路由实例
export default router

其中的Login就是自己在views中创建的组件:Login.vue

挂载到Vue实例中

main.js中的Vue实例中挂载导出的路由实例router

import Vue from 'vue'
import App from './App'

new Vue({
  el: '#app',
  router,
  render: h => h(App)
})

使用路由

通过<router-link><router-view>使用路由

<template>
  <div id="app">
     <router-link to="/home">首页</router-link>
     <router-link to="/about">关于</router-link>
     <router-view></router-view>
  </div>
</template>

<script>
import Vue from 'vue';

Vue.config.productionTip = false;

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

<style>
</style>

<router-link>还有一些其他属性:

  • tag: tag可以指定<router-link>之后渲染成什么组件, 比如上面的代码会被渲染成一个<li>元素, 而不是<a>
  • replace: replace不会留下history记录, 所以指定replace的情况下, 后退键返回不能返回到上一个页面中
  • active-class: 当<router-link>对应的路由匹配成功时, 会自动给当前元素设置一个router-link-activeclass,
  • to: 用于指定跳转的路径.

3、动态路由

静态路由是路由路径和定义时路由信息保持完全一致。动态路由是指可以在路由定义中传入一些路由参数,这个路由参数可以在组件中通过 props 数据来获取。

routes: [
 {
 path: '/users/:username/post/:postid',
 name: 'Users',
 component: UserComponent,
 }
 ]

下面对模式,匹配的路径和通过$route.params 获取的信息进行举例说明,具体如表格所示:

模式匹配路径$route.params
/user/:username/user/zhangsan{username:‘zhangsan’}
/user/:username/post/:postId/user/zhangsan/post/3{username:‘zhangsan’,postId:‘3’}

路由参数传递

路由传递参数主要有两种类型: paramsquery

通过params类型:

配置路由格式: /router/:id
传递的方式: 在path后面跟上对应的值
传递后形成的路径: /router/123, /router/lili

<template>
  <div id="app">
     <router-link to="/home">首页</router-link>
     <router-link to="/about">关于</router-link>
     <button @click="toHome">首页</button>
     
      <router-view/>
  </div>
</template>

<script>
  export default {
    name: 'App',
    methods: {
     toHome() {
       this.$router.push({
       path: '/login/' + 123
      })
    }
  }
}
</script>

通过query类型:

配置路由格式: /router, 也就是普通配置
传递的方式: 对象中使用querykey作为传递方式
传递后形成的路径: /router?id=123, /router?id=lili

<template>
  <div id="app">
     <router-link to="/home">首页</router-link>
     <router-link to="/about">关于</router-link>
     <button @click="toHome">首页</button>
     
     <router-view/>
  </div>
</template>

<script>
  export default {
    name: 'App',
    methods: {
     // 使用name跳转
     toHome() {
       this.$router.push({
       name: 'home',
       query: {name: 'lili', sex: 2}
      })
      // 使用path跳转
     toHome() {
       this.$router.push({
       path: 'home',
       query: {name: 'lili', sex: 2}
      }) 
    }
  }
}
</script>

Home.vue

<template>
  <div>
    <h1>用户信息</h1>
      <h2>params传参信息</h2>
        <h5>params:{{$router.params}}</h5>
        <h5>params:{{$router.params.name}}</h5>
        <h5>params:{{$router.params.sex}}</h5>
   
      <h2>query传参信息</h2>
       <h5>query:{{$router.query}}</h5>
       <h5>query:{{$router.query.name}}</h5>
       <h5>query:{{$router.query.sex}}</h5>
  </div>
</template>

<script>
  export default {
    name: 'Home'
  }
</script>

还有一个在路由参数中常用 props 传递路由参数。

routes:
 {
 path: '/users/:id',
 name: 'Users',
 component: UserComponent,
 // 把当前路由参数作为 props 数据传递给路由组件
 // 降低了路由组件和当前路由定义的耦合性
 props:true
 }

UserComponent.vue 文件:

<template>
 <div class="user">
 this is user-component
 id = {{id}}
 </div>
</template>
<script>
export default {
 name: 'UserComponent',
 props: ['id']
}
</script>

4、获取路由参数

获取参数通过$route对象获取:在使用了vue-router的应用中,路由对象会被注入每个组件中,赋值为 this.$route ,并且当路由切换时,路由对象会被更新。如上面的参数传递实例:

      <h2>params传参信息</h2>
        <h5>params:{{$router.params}}</h5>
        <h5>params:{{$router.params.name}}</h5>
        <h5>params:{{$router.params.sex}}</h5>
   
      <h2>query传参信息</h2>
       <h5>query:{{$router.query}}</h5>
       <h5>query:{{$router.query.name}}</h5>
       <h5>query:{{$router.query.sex}}</h5>

5、嵌套路由

是指在路由的定义中包含子路由的定义。实际使用中,很可能会需要在路由中嵌套子路由,指定路由 /user/:id ,可以在该路由组件内容渲染其它路由组件(如/user/:id/posts 或 /user/:id/profies)。
用法如下:

children: [
 {
 path: "",
 component: 路由名
 },
 {
 path: "路径名",
 component: 路由名
  }
]

命名路由视图

使用<router-view>可以使用 name 属性为其设置名称,即命名路由的视图简称命名视图。若未添加 name属性,则默认名称为default

<!-- router-view:渲染路由页面显示的区域 -->
 <router-view/> <!--about -->
 <router-view name="content"></router-view> <!-- UserComponent -->
import About from './views/About.vue';
routes: [ 
 {
 path: "/about",
 name: "about",
 components: {
 default: About,
 content: UserComponent
 }
 }
 ]

在上面实例中,About组件是默认的渲染视图,UserComponent组件是渲染的 namecontent 的视图。

6、路由导航守卫

当动态路由发生切换时,可以使用路由导航守卫处理路由的变化。即简单的说就是vue-router导航守卫监听监听路由的进入和离开的,什么是路由导航守卫可以简单理解为路由组件的生命周期回调函数如beforeEachafterEach等钩子回调函数,它们会在路由即将改变前和改变后触发。

// 路由导航守卫
// 作用:在第一次进入当前路由组件之前被调用
// 使用场景:获取 ajax 数据
beforeRouteEnter(to, from, next) {
 // to:表示要进入的路由组件
 // from:表示将要离开的路由组件
 // next:表示后续操作函数
 // 此时还未进入到组件中,故不能使用 this 获取当前组件的实例
 next(function(app) {
 // 进入到当前组件后,才执行的回调
 // 此时回调参数 app 表示当前组件的实例对象
 axios.get('/users/' + app.id).then(res => {
 app.user = res.data.data;
 });
 });
}
beforeRouteUpdate(to, from, next) {
 // 此时,可以使用 this 表示当前组件对象
 const app = this;
 // 发送 ajax 请求
 // this 表示切换前的状态
 // to 表示要切换到的路由对象 route
 axios.get('/users/' + to.params.id).then(res => {
 app.user = res.data.data;
 });
 // 执行后续
 next();
}

全局路由导航守卫

全局路由导航守卫可以应用于用户登陆校验,默认情况下显示的是首页,但是只有用户登陆以后才能进入首页,才能查看后台管理页面,否则用户没有处于登陆状态,需要跳转到登陆页面,针对这个问题使用全局路由导航守卫。全局路由导航守卫介绍如下:

// 全局路由导航守卫
router.beforeEach((to, from, next) => { 
});
  • to: 即将要进入的目标的路由对象.
  • from: 当前导航即将要离开的路由对象.
  • next: 调用该方法后, 才能进入下一个钩子.

实例:

router.beforeEach((to, from, next) => {
    if (to.path === '/login') return next()
    const tokenStr = window.sessionStorage.getItem('token')
    if (!tokenStr) return next('/login')
    next()
})

编程式路由导航

编程式路由导航也是路由的重要部分,之前实现路由跳转有两种方式,其一是在浏览器中输入地址实现路由跳转,其二是使用<router-link> 触发路由跳转。

methods: {
 login(){
 if(登陆成功){
 //实现页面跳转
 this.$router.push('/');
 }
 }
}
  • push( ): 跳转到指定的路由地址,并把当前地址写入到history 中,参数可以是字符串路径或描述地址信息的对象:
参数类型参数
字符串router.push(‘home’)
对象router.push({path:‘home’})
命名的路由router.push({name:user,params:{userId:1}})
  • replace( ):跳转到指定路由,它不会向history 添加新记录,而是替换掉当前的 history 记录。
  • go( n ):前进或后退指定步
    – router.go(1):前进一步,等同于 router.forward( )
    – router.go(-1) :后退一步,等同于 router.back( )
    – router.go(0) :刷新当前页面全局路由导航守卫

7、路由的懒加载

路由懒加载的主要作用就是将路由对应的组件打包成一个个的js代码块,只有在这个路由被访问到的时候, 才加载对应的组件.

懒加载的方式:

方式一: 结合Vue的异步组件和Webpack:

const Login = resolve => { require.ensure(['../views/Login .vue'], () => { resolve(require('../views/Login .vue')) })};

方式二: AMD写法

const Login = resolve => require(['../views/Login.vue'], resolve);

方式三: 在ES6中, 有更加简单的写法来组织Vue异步组件和Webpack的代码分割

const Login = () => import('../views/Login.vue')

8、vue-router钩子函数

全局前置守卫: router.beforeEach
全局解析守卫: router.beforeResolve
全局后置钩子: router.afterEach
路由独享的守卫: beforeEnter
组件内的守卫: beforeRouteEnter 、 beforeRouteUpdate 、 beforeRouteLeave

9、 route 和 router 的区别

  • route 是“路由信息对象”,包括 path , params , hash , query , fullPath , matched , name 等路由信息参数,想要导航到不同URL,则使用$router.push方法。
  • router 是“路由实例对象”,为当前router跳转对象里面可以获取name、path、query、params等 。也包括了路由的跳转方法( push 、 replace ),钩子函数等。

以上是关于前端开发简说Vue-router路由的主要内容,如果未能解决你的问题,请参考以下文章

vue-router之前端路由的学习总结

基于vscode开发vue3项目的详细步骤教程 3 前端路由vue-router

Vue-router路由系统介绍

前端路由简介以及vue-router实现原理

前端路由简介以及vue-router实现原理

为某些路由禁用 vue-router?或者如何运行 SPA 后端和非 SPA 前端?