Vue路由使用(router)

Posted 一杆老狙

tags:

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

介绍

vue-router相当于vue内部跳转链接,将需要切换的页面在vue-router里注册,在项目里配置就能完成页面的切换,它不仅能完成项目的切换,还能实现参数的传递,它还有个很重要的功能路由导航守卫(导航守卫分为前置导航守卫,后置导航守卫,组件内置导航守卫,常用就是前置导航守卫,设置用户登录可访问的界面和未登录可访问的界面,也相当于二次拦截,(axios请求拦截器是第一次拦截))。

路由跳转和传参

重点:
在vue-router中,有两大对象被挂载到了实例this
$route(只读、具备信息的对象);
$router(具备功能的函数);

  • 1.router-link(类似a标签)

路由配置:

// 路由配置
 
   path: '/pkproperties', // 路径
   name:'pkproperties', // 路由名,path路径必写,用name跳转的时候是根据name名找到path进行跳转
   component: () => import('@/views/pkproperties'), // 组件(组件文件名为index的可省略),路由懒加载写法
   redirect: '', // 路由重定向,就是当一个页面需要切换多个路由的时候,这里面填的是首次进入页面展示的路由组件地址
   hidden: truechildren: [] // 嵌套路由,当一页有很多路由需要切换的时候,就需要用到嵌套路由
  ,
  
// 组件内使用
   <router-link to="/pkproperties">点击跳转</router-link>  // path路径跳转
   <router-link to="name:'pkproperties',query:id:1">点击跳转</router-link>  // 使用命名路由name跳转

传参配置:

 
   path: '/pkproperties', // 路径
   name:'pkproperties', // 路由名,path路径必写,用name跳转的时候是根据name名找到path进行跳转
   component: () => import('@/views/pkproperties'), // 组件(组件文件名为index的可省略)
   hidden: true
  ,
   // 使用命名路由传参,可以传递基本数据类型和数组和对象
   <router-link to="name:'pkproperties',query:id:1">点击跳转</router-link>  // name名跳转,query传递参数
   <router-link to="name:'pkproperties',params:id:1">点击跳转</router-link>  // name名跳转,params传递参数
   
   this.$route.query.id // 获取传递的参数(.传递参数的键名)
   this.$route.params.id // 获取传递的参数(.传递参数的键名)
  • 2.编程式路由跳转(最常用的,不受时机、条件的限制)

路由配置:


   path: '/pkproperties', // 路径
   name:'pkproperties', // 路由名,path路径必写,用name跳转的时候是根据name名找到path进行跳转
   component: () => import('@/views/pkproperties'), // 组件(组件文件名为index的可省略)
   hidden: true
  ,

传参配置:

methods:
   onSkipTransferParameters()
   // params传参
        this.$router.push(
           name: "pkproperties",
           params:  
           name: '小明',
           id: 1,
          ,
        );
     onSkipTransferParameters()
   // query传参
        this.$router.push(
           name: "pkproperties",
           query:  
           name: '小明',
           id: 1,
          ,
        );
   
 // 获取传递的参数
 this.$route.params.name // 获取就是在当前跳转的组件内调用$route实例,是用params就.params.键名获取值
 this.$route.query.name // 获取就是在当前跳转的组件内调用$route实例,是用query就.query.键名获取值

query传参在刷新界面后传递的数据不会丢失params传递的参数刷新界面后会丢失参数

  • 3.路由重定向redirect需要用到传参的业务
    path:"/", redirect: path:"pkproperties", query:Pid:'1' ,
    path:"pkproperties", component: ()=>import("../views/pkproperties") 

解决路由重复点击路由沉积的问题

// 把这段代码直接粘贴到router/index.js中的Vue.use(VueRouter)之前
const originalPush = VueRouter.prototype.push;
  VueRouter.prototype.push = function (location) 
  return originalPush.call(this, location).catch(err =>  )
;

注意:一定要写在 Vue.use(VueRouter)之前否则无效

解决路由跳转后不能回到顶部的页面顶部的问题

在跳转到的组件里配置下面的代码即可

 mounted() 
    /**
     * 路由跳转回到顶部
     */
    // chrome
    document.body.scrollTop = 0;
    // firefox
    document.documentElement.scrollTop = 0;
    // safari
    window.pageYOffset = 0;
  ,

路由导航守卫和案例展示

  • 路由前置导航守卫(beforeEach
    // 全局导航守卫beforeEach
router.beforeEach((to, from, next) => 
	// to要到哪个路由去
    // from从哪个路由来
    // next下一步(无论失败与否都要调用,否则会阻止程序继续执行)

案例1中使用(拦截未登录用户和白名单设置):

permission.js文件下配置(permission文件最好和main文件在同一目录下创建)

import router from './router'
import  getToken  from '@/common/TokenStore'

const whiteList = ['/login', '/register'] // 白名单登录注册界面无需验证Token是否登录直接放行

// 全局导航守卫beforeEach
router.beforeEach((to, from, next) => 
	// 白名单中路由直接放行
	if (whiteList.indexOf(to.path) !== -1) 
		next()
		return
	
	// 判断需要登录身份认证的路由
	const token = getToken() // 获取token
	if (token) 
		next()
	 else 
		next(`/login`) // 如果登录不存在,重定向到登录界面
	
)

main.js文件下引入即可

import './permission' // 引入即可

案例2中使用(设置Tokne失效实现拦截,Tokne失效就导航会登录界面重新登录,未失效就不执行操作)

login.vue(登录组件登录成功后保存Token和保存获取Token的当前时间戳在本地)

    methods: 
 
      // 登录
      handleLogin() 
        this.$axios.post('/api/Login',
         username: this.loginForm.username, // 用户名
         password: this.loginForm.password // 密码
        ).then(res =>  
          if(res.data.code != 0) return this.$message.error(res.data.message) // code 不等于0,返回失败的结果,(这的判断参数是根据后端返回的数据进行的,不是固定的)
          if(res.data.code == 0)
            this.$message.success('登录成功')
            // 存储token开始时间
            window.localStorage.setItem('tokenStartTime',new Date().getTime())
            // 存储token
            window.localStorage.setItem('token',res.data.data.token)
            this.$router.push('/home/ks')
          else 
            this.$message.error('登录失败')
          
        )
      

permission.js(将保存的Token获取时间和当前时间进行一个差值的比较,如果小于我们设定的Token失效时间,就证明登录没有过期可继续访问,如果大于就登录过期Token失效需要重新登录获取。)

// 导入element提示语的组件可以去element-ui查看用法,这是按需引入的
import 
    Message
 from 'element-ui'
 
 
// 添加请求拦截器
// 拦截器的第二部分,第一部分在main.js里面
router.beforeEach((to, from, next) => 
 
  // 获取存储localStorage的token
  let token = window.localStorage.getItem('token')
  // 获取存储token的开始时间
  const tokenStartTime = window.localStorage.getItem('tokenStartTime')
  // 后台给出的token有效时间为一天,这个是后端给的时间以后端为准
  const timeOver = 86400000
  // 获取当前时间
  let date = new Date().getTime()
  // 当前时间减去获取Token的时间如果大于说明是token过期了
  if(date - tokenStartTime > timeOver) 
      token = null // Token过期赋值为null
  
  // 如果token过期了
  if (!token) 
    if (to.path == '/login') return next()
    // 注意要import element的Message组件
    Message.error("登录状态过期,请重新登录")
    return next('/login')
    // 如果token没有过期,又是选择了登录页面就直接重定向到首页,不需要重新输入账户密码
   else if (to.path == '/login') 
    return next('/home/ks')
  
  next()
 
)
export default router
  • 全局后置守卫(afterEach
router.afterEach((to,from)=>)
  • 组件内守卫(相当于给组件增加生命周期
beforeRouteEnter 进入组件之前
beforeRouterEnter(to,from,next)

beforeRouteUpdate 组件被复用时调用
beforeRouterUpdate(to,from,next)

beforeRouteLeave 离开组件时调用
beforeRouteLeave(to,from,next)

访问外部链接

  • vue内部跳转可以通过vue-router中的this.$router.push()和rout-link 来实现,这里在说一下想要访问外部链接的方法

1.window.location.href = url(不新开一个页面,直接在当前页面跳转)

methods:
  onSkip()
    window.location.href = "http://xxx.xxx.xxx"
  

2.window.open(“url”, “_blank”)(打开一个新页面跳转)

methods:
  onSkip()
    window.open("https://xxx.xxx.xxx/", "_blank");
  

3.手动创建a标签,然后默认点击

 var a = document.createElement("a");
     a.setAttribute("href", "www.baidu.com");
     a.setAttribute("target", "_blank");
     a.click();

vue_路由Router

使用路由

Vue Router 是 Vue.js 官方的路由管理器。它和 Vue.js 的核心深度集成,让构建单页面应用变得易如反掌

  • 安装
    1. vue项目创建时选择使用路由,项目将自动在根实例中注册 router 选项,
      该 router 实例会注入到根组件下的所有子组件中,且子组件能通过 this.$router 访问到
    2. 假设vue项目创建没有选择使用路由,手动将路由注册到根实例中
      • $ npm install vue-router --save
      • 手动创建目录 src/router/index.js
  • 使用路由(项目初始化选择使用路由后将自动生成下列代码)
import Vue from ‘vue‘
import Router from ‘vue-router‘
import Home from ‘@pages/home/Home‘
Vue.use(Router)
export default new Router({
  routes: [{
   path: ‘/‘,
   name: ‘Home‘,
   component: Home
  }]
})
// 注册到根实例 // main.js
import router from ‘./router‘
new Vue({
  el: ‘#app‘,
  router,
  components: { App },
  template: ‘<App/>‘
})

前端路由优缺点

优点
用户体验好,不需要每次都从服务器全部获取,快速展现给用户
缺点
不利于SEO
使用浏览器前进,后退的时候会从新发送请求,没有合理的利用缓存
单页面无法记住之前滚动的位置,无法在前进,后退的时候记住滚动的位置

动态路由匹配,注意是route不是router

模式 匹配路径 this.$route.params
/goods/:goodsId /goods/0001 { goodsId: ‘0001‘ }
/goods/:goodsId/user/:name /goods/0001/user/iphone { goodsId: ‘0001‘, name: ‘iphone‘ }

嵌套路由

// router/index.js
routes: [{ 
  path: ‘/user/:id‘, 
  component: User,
  children: [{
    // 当 /user/:id/profile 匹配成功,
    // UserProfile 会被渲染在 User 组件的 <router-view> 中
    path: ‘profile‘, // 注意不要加斜杠/profile,加了斜杠就是根路由
    component: UserProfile
  }, {
    // 当 /user/:id/posts 匹配成功
    // UserPosts 会被渲染在 User 组件的 <router-view> 中
    path: ‘posts‘,
    component: UserPosts
  }]
}]

<router-link to="/user/001/profile">跳转</router-link>

编程式路由

编程路由就是通过js来实现页面的跳转
this.$router.push(params)
this.$router.replace(params)
router.replace唯一的不同就是,它不会向history添加新记录, 替换掉当前的history记录。也就是没有前进后退功能
params: 可以是字符串,对象和参数传递

注意: 这里获取使用的是this.route.query(url地址问号拼接的参数)和获取的动态路由.params(动态参数)不同

params 跳转路径 this.$route.query this.$route.params
‘/home‘ /home
{path: ‘/home‘} /home
{path: ‘/home?user=jack‘} /home?user=jack {user: ‘jack‘}
{path: ‘/home‘,query:{user:‘jack‘,pass:‘1234‘}} /home?user=jack&pass=1234 {user:‘jack‘,pass:‘1234‘}
{name: ‘user‘, params: {userId: ‘123‘}} /user/123 {userId:‘123‘}
{path: ‘/user?count=10‘, params: { userId: ‘123‘ }} /user?count=10 {count: 10}

注意:name是路由配置里面的name的值(命名路由),如果提供了 path,params 会被忽略,
router.go(n)
这个方法的参数是一个整数,意思是在 history 记录中向前或者后退多少步
操作 History
router.push、 router.replace 和 router.go 跟 window.history.pushState、 window.history.replaceState 和 window.history.go好像,实际上它们确实是效仿 window.history API 的

命名路由

routes: [{
  path:‘/user/:userId‘,
  name: ‘user‘,
  component: User
}]
// 要链接到一个命名路由,可以给router-link的to属性传一个对象:
<router-link :to="{ name: ‘user‘, params: { userId: 123 }}">User</router-link>
// 和编程式路由调用一样router.push({ name: ‘user‘, params: { userId: 123 }})

命名视图

使用场景:有时候想同时(同级)展示多个视图,而不是嵌套展示,例如创建一个布局

<router-view class="view one"></router-view>
<router-view class="view two" name="sidebar"></router-view>
<router-view class="view three" name="main"></router-view>
// 路由配置
routes: [{
  path: ‘/‘,
  components: {
    default: Foo, // 没有给name属性的router-view默认渲染视图
    sidebar, 
    main
  }
}]

vue默认跳转router-link使用a标签渲染,当我们不想使用a标签渲染时,又想使用跳转功能可以使用tag属性,来代替a标签渲染,例如:

<ul>
  // 页面最终会以li标签渲染,
  <router-link tag="li" to="/">列表1</router-link>
</ul>

路由懒加载

当打包构建应用时,JavaScript 包会变得非常大,影响页面加载。如果我们能把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,这样就更加高效了。

// router 配置
routes: [{
  path: ‘/user‘,
  name: ‘user‘,
  component: () => import(‘./my-async-component‘)
}]
// 全局组件配置
Vue.component(‘async-component‘, () => import(‘./my-async-component‘)))
// 局部组件配置
export default {
  // ....
  components: {
    ‘async-component‘: () => import(‘./my-async-component‘)
  }
}

更多路由配置查看

以上是关于Vue路由使用(router)的主要内容,如果未能解决你的问题,请参考以下文章

vue.js路由vue-router——简单路由基础

Vue.js:在 vue.router 路由中使用 mixin 函数

vue_路由Router

Vue之 vue-router

Vue--路由「Vue-router」的使用

在使用 vue.js 和 vue-router 显示路由之前,Rest API 加载数据的速度不够快