vue-router路由详解

前端路由的核心是什么呢?

改变URL,但是页面不进行整体的刷新。

如何实现呢?

URL的hash

  • URL的hash也就是锚点(#), 本质上是改变window.location的href属性.
  • 我们可以通过直接赋值location.hash来改变href, 但是页面不发生刷新
    在这里插入图片描述
location.hash='foo'        →     http://localhost:8080/#foo

HTML5的history模式
history接口是HTML5新增的, 它有五种模式改变URL而不刷新页面.

在这里插入图片描述

  • history.pushState({data}, ‘title’, ‘url’) 栈结构—先进后出(出栈/返回上一步:history.back())
    参数第一位:传数据
    参数第二位:设置标题
    参数第三位:地址
	history.pushState({}, '', 'home')    →    http://localhost:8080/home  (可以使用返回箭头)
  • history.replaceState({data},“title”,“url”)
history.replaceState({},"","abut")   →   http://localhost:8080/abut    (不能使用返回箭头,被替换)
  • history.go()
    history.go(-1) === history.back() 退栈
    history.go(2) 进栈2个

补充说明: 上面只演示了三个方法 因为
history.back() 等价于 history.go(-1)
history.forward() 则等价于 history.go(1)
这三个接口等同于浏览器界面的前进后退。

安装和使用vue-router

安装vue-router
npm install vue-router --save
在src目录里新建 router文件夹并创建index.js配置router

  1. 引入组件
	import VueRouter from 'vue-router'
	import Vue from 'vue'
  1. 通过vue.use() 安装插件
	Vue.use(VueRouter)
  1. 创建router对象
	const router = new VueRouter({
	    //配置路由和组件直接的应用关系
	    routes
	})
  1. 将routers配置抽离
    const routes = [

    ]
  2. 将router对象挂载到vue实例mian.js中
	export default router

在这里插入图片描述
6. 创建路由组件并引入到路由配置页面配置组件联系

	import Home from '../components/Home'
	import Abut from '../components/Abut'
	const routes = [
	    //设置默认页面
	    {
	        path:'',
	        component:Home
	    },
	    {
	        path:'/home',
	        component:Home
	    },
	    {
	        path:'/abut',
	        component:Abut
	    }
	]
  1. 在APP.vue中使用路由
    使用路由: 通过 router-linkrouter-view在这里插入图片描述

路由的默认路径–redirect重定向

	const routes = [
	    {
	        path:'/',
	        redirect:Home
	    },
	]

设置路径模式—一般使用HTML5的history模式

	const router = new VueRouter({
	    routes,
	    mode:'history'
	})

配置文件完整代码

	import Vue from 'vue'
	import VueRouter from 'vue-router'
	
	import Home from '../components/Home'
	import Abut from '../components/Abut'
	
	Vue.use(VueRouter)
	
	const routes = [
	    {
	        path:'/',
	        redirect:Home
	    },
	    {
	        path:'/home',
	        component:Home
	    },
	    {
	        path:'/abut',
	        component:Abut
	    }
	    
	]
	
	const router = new VueRouter({
	    routes,
	    mode:'history'
	})
	export default router

router-link属性

  • to:用于指定跳转的路径。
  • tag: tag可以指定router-link之后渲染成什么组件, 比如上面的代码会被渲染成一个li元素, 而不是a。
  • replace: replace不会留下history记录, 所以指定replace的情况下, 后退键返回不能返回到上一个页面中。
  • active-class: 当router-link对应的路由匹配成功时, 会自动给当前元素设置一个router-link-active的class, 设置active-class可以修改默认的名称。
<template>
  <div id="app">
    <router-link to="/home" tag="li" active-class="active" replace>首页</router-link>
    <router-link to="/abut" active-class="active" replace>关于</router-link>
    <router-view></router-view>
  </div>
</template>

修改linkActiveClass

const router = new VueRouter({
    routes,
    mode:'history',
    linkActiveClass:'active'  
})

代码实现跳转

<template>
  <div id="app"> 
    <button @click="homeClick">首页</button>
    <button @click="abutClick">关于</button>
    <router-view></router-view>
  </div>
</template>
<script>
export default {
  methods: {
    homeClick() {
      this.$router.push('/home')
      //不需要返回功能
      //this.$router.replace('/home')
    },
    abutClick() {
      this.$router.push('/abut')
    }
  }
}
</script>

解决多次点击报错问题:在main.js中添加一下代码

import Router from 'vue-router'

const originalPush = Router.prototype.push
Router.prototype.push = function push(location) {
  return originalPush.call(this, location).catch(err => err)
}

动态路由

传递参数的方式

传递参数主要有两种类型: params/query和JavaScript传参

  • 方式一:params传参
{
        path:'/home/:id',
        component:Home
    },

    <router-link :to="/home/+1234">首页</router-link>
    <script>
    	  data() {
		    return {
		      id: 1234
		    }
		  },
    </script>
	<h2>我是首页的参数{{$route.params.id}}</h2>

在这里插入图片描述

  • 方式一:query传参
    在router-link中进行
      <router-link :to="{
        path: '/abut',
        query: {
          name: 'zhangsan',
          age: 18,
          height: 160
        }
      }">关于</router-link>
      //获取参数
       <h2>{{$route.query}}</h2>
  • 传递参数方式二: JavaScript代码
    在这里插入图片描述
    获取参数通过$route对象获取
    在这里插入图片描述
    备注:
  • this.$router 指VueRouter实例,想要导航到不同URL,则使用router.push方法
  • this.$route 指当前router跳转对象(当前活跃对象)里面可以获取name、path、query、params等

嵌套路由

嵌套路由是一个很常见的功能
比如在home页面中, 我们希望通过/home/news和/home/message访问一些内容.一个路径映射一个组件, 访问这两个路径也会分别渲染两个组件.

实现嵌套路由有两个步骤:
创建对应的子组件, 并且在路由映射中配置对应的子路由.
在组件内部使用router-view标签.
在这里插入图片描述在这里插入图片描述

导航守卫

  • vue-router提供的导航守卫主要用来监听监听路由的进入和离开的.
  • vue-router提供了beforeEach和afterEach的钩子函数, 它们会在路由即将改变前和改变后触发.
前置钩子(hook)beforEach():跳转之前执行
router.beforeEach((to, from, next) => {
	next(),  //下一步
    //...
})

导航钩子的三个参数解析:
to: 即将要进入的目标的路由对象.
from: 当前导航即将要离开的路由对象.
next: 调用该方法后, 才能进入下一个钩子.

例:给每个页面设置title

首先, 我们可以在钩子当中定义一些标题, 可以利用meta来定义。
在这里插入图片描述
其次, 利用导航守卫,修改我们的标题。

  //如果首次进入的title 为undefined使用matched
 window.document.title = to.matched[0].meta.title 

在这里插入图片描述

后置钩子(hook)afterEach():跳转之后执行
router.afterEach((to, from) => {
    //...  这里不需要调用next()
})
  • 补充一:如果是后置钩子, 也就是afterEach, 不需要主动调用next()函数.
  • 补充二: 上面我们使用的导航守卫,被称之为全局守卫.
  • 路由独享的守卫.
  • 组件内的守卫.

更多内容, 可以查看官网进行学习: 官网地址

keep-alive

keep-alive 是 Vue 内置的一个组件,可以使被包含的组件保留状态,或避免重新渲染。

它们有两个非常重要的属性:
include - 字符串或正则表达,只有匹配的组件会被缓存
exclude - 字符串或正则表达式,任何匹配的组件都不会被缓存

router-view 也是一个组件,如果直接被包在 keep-alive 里面,所有路径匹配到的视图组件都会被缓存:

      <keep-alive>
        <router-view include='home'></router-view>
      </keep-alive>

通过create声明周期函数来验证
当使用keep-alive组件时可调用activated() 和 deactivated()方法

//活跃时
  activated() {
    console.log('activivated');
  },
  //不活跃时(离开时)
  deactivated() {
    console.log('deactivated');
    
  },

引入:路由嵌套时使用keep-alive效果失效问题以home页面为例
解决思路:定义变量path到data值:

export default {
  name:'home',
  data() {
    return {
      path: '/home'
    }
  }
}

当home处于活跃时设置地址

  activated() {
    this.$router.push(this.path)
  },

使用组件守卫保存当前要离开时的页面路径

beforeRouteLeave (to, from, next) {
    this.path = this.$route.path;
    next()
  }

拓展:解决路由js绑定地址多次报错问题:
复制以下代码到main.js中

import Router from 'vue-router'

const originalPush = Router.prototype.push
Router.prototype.push = function push(location) {
  return originalPush.call(this, location).catch(err => err)
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值