【Vue】路由vue-router详解

在这里插入图片描述


一、路由概念和原理

简介:这里的路由并不是指我们平时所说的硬件路由器,这里的路由就是SPA(单页应用)路径管理器。再通俗的说,vue-router就是WebApp的链接路径管理系统。

路由用于设定访问路径,并将路径和组件映射起来。传统的页面应用,是用一些超链接来实现页面切换和跳转的。在vue-router单页面应用中,则是路径之间的切换,也就是组件的切换。路由模块的本质 就是建立起url和页面之间的映射关系

实现原理

SPA(single page application):单一页面应用程序,只有一个完整的页面;它在加载页面时,不会加载整个页面,而是只更新某个指定的容器中内容。单页面应用(SPA)的核心之一是: 更新视图而不重新请求页面;vue-router在实现单页面前端路由时,提供了两种方式:Hash模式和History模式;根据mode参数来决定采用哪一种方式。


二、安装

  • 使用npm安装
npm install vue-router --save
  • 使用vue ui 安装

在这里插入图片描述

  • package.json 出现证明安装成功

在这里插入图片描述


三、模式

Hash模式

大家如果留心观察就会发现,之前我们做的页面的 URL 里有一个 # 号,这个 # 号有什么含义呢?

vue-router 默认 hash 模式—— 使用 URL 的 hash 来模拟一个完整的 URL,于是当 URL 改变时,页面不会重新加载。 hash(#)是URL 的锚点,代表的是网页中的一个位置,单单改变#后的部分,浏览器只会滚动到相应位置,不会重新加载网页,也就是说hash 出现在 URL 中,但不会被包含在 http 请求中,对后端完全没有影响,因此改变 hash 不会重新加载页面;同时每一次改变#后的部分,都会在浏览器的访问历史中增加一个记录,使用”后退”按钮,就可以回到上一个位置;所以说Hash模式通过锚点值的改变,根据不同的值,渲染指定DOM位置的不同数据。hash 模式的原理是 onhashchange 事件(监测hash值变化),可以在 window 对象上监听这个事件


History模式

由于hash模式会在url中自带#,如果不想要很丑的 hash,我们可以用路由的 history 模式,只需要在配置路由规则时,加入"mode: ‘history’",这种模式充分利用了html5 history interface 中新增的 pushState() 和 replaceState() 方法。这两个方法应用于浏览器记录栈,在当前已有的 back、forward、go 基础之上,它们提供了对历史记录修改的功能。只是当它们执行修改时,虽然改变了当前的 URL ,但浏览器不会立即向后端发送请求

当你使用 history 模式时,URL 就像正常的 url,例如 http://yoursite.com/user/id,比较好看!

不过这种模式要玩好,还需要后台配置支持。因为我们的应用是个单页客户端应用,如果后台没有正确的配置,当用户在浏览器直接访问 http://oursite.com/user/id 就会返回 404,这就不好看了。

所以呢,你要在服务端增加一个覆盖所有情况的候选资源:如果 URL 匹配不到任何静态资源,则应该返回同一个 index.html 页面,这个页面就是你 app 依赖的页面。

 export const routes = [ 
  {path: "/", name: "homeLink", component:Home}
  {path: "/register", name: "registerLink", component: Register},
  {path: "/login", name: "loginLink", component: Login},
  {path: "*", redirect: "/"}]

此处就设置如果URL输入错误或者是URL 匹配不到任何静态资源,就自动跳到到Home页面


四、index.js文件

1:下载

2:在main.js中引入 import VueRouter from ‘vue-router’;

3:安装插件Vue.use(VueRouter);

4:创建路由对象并配置路由规则[{path:’/home’,component:Home}]});

5:将其路由对象传递给Vue的实例,options中加入 router:router

6:在app.vue中留坑

// 配置路由相关的信息,main.js文件中引入
import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '../views/Home.vue'


// 1.通过Vue.use(插件), 安装插件

Vue.use(VueRouter)


// 2.创建VueRouter对象
const routes = [
  {
    path: '/',
    name: 'Home',
    component: Home
  },
  {
    path: '/about',
    name: 'About',
    // route level code-splitting
    // this generates a separate chunk (about.[hash].js) for this route
    // which is lazy-loaded when the route is visited.
    component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
  }
]

// 配置路由和组件之间的应用关系
const router = new VueRouter({
  //配置模式为history
  mode: 'history',
  base: process.env.BASE_URL,
  routes
})

// 3.将router对象传入到Vue实例
export default router


五、路由实例及其属性

$route 和 $router 的区别

  • $route 是“路由信息对象”
  • $router 是“路由实例”对象

将这两者console.log打印出来:

在这里插入图片描述

在这里插入图片描述

$route 是“路由信息对象”

包括 path,params,hash,query,fullPath,matched,name 等路由信息参数。

$route.path
字符串,对应当前路由的路径,总是解析为绝对路径,如 “/order”。

$route.params
一个 key/value 对象,包含了 动态片段 和 全匹配片段,
如果没有路由参数,就是一个空对象。

$route.query
一个 key/value 对象,表示 URL 查询参数。
例如,对于路径 /foo?user=1,则有 $route.query.user为1,
如果没有查询参数,则是个空对象。

$route.hash
当前路由的 hash 值 (不带 #) ,如果没有 hash 值,则为空字符串。

$route.fullPath
完成解析后的 URL,包含查询参数和 hash 的完整路径。

$route.matched
数组,包含当前匹配的路径中所包含的所有片段所对应的配置参数对象。

$route.name 当前路径名字

$router 是“路由实例”对象

即使用 new VueRouter创建的实例,包括了路由的跳转方法,钩子函数等

$router常见跳转方法:

<button @click="goToMenu" class="btn btn-success">Let's order!</button>
.....
<script>
  export default{
    methods:{
      goToMenu(){
        this.$router.go(-1)//跳转到上一次浏览的页面
        this.$router.replace('/menu')//指定跳转的地址
        this.$router.replace({name:'menuLink'})//指定跳转路由的名字下
        this.$router.push('/menu')//通过push进行跳转
        this.$router.push({name:'menuLink'})//通过push进行跳转路由的名字下
      }
    }
  }
</script>

$router.push$router.replace的区别:

  • 使用push方法的跳转会向 history 栈添加一个新的记录,当我们点击浏览器的返回按钮时可以看到之前的页面。
  • 使用replace方法不会向 history 添加新记录,而是替换掉当前的 history 记录,即当replace跳转到的网页后,‘后退’按钮不能查看之前的页面

六、router标签

router-link及其属性

  • 最终默认会渲染成a标签 <a></a>
  • to属性
  • tag属性
  • replace属性

to属性:配置的path值,如果要导航到默认首页,只需要写成 to="/" ,

# 点击跳转到“/”路径,默认为a标签
<router-link to="/">Home</router-link> |

tag属性:决定渲染类型

# 点击跳转到"/",类型修改为button按钮
<router-link to="/" tag="button">Home</router-link> |

replace属性:不会留下history记录

# 点击跳转到"/"后,不能在浏览器中使用返回上一个页面
<router-link to="/" tag="button" replace>Home</router-link> |

active-class属性:通常不会使用

  • 在进行高亮显示的导航菜单或者底部tabbar时,会使用到该类
# 点击跳转到"/"后,不能在浏览器中使用返回上一个页面
<router-link to="/" replace active-class="active">Home</router-link> |

七、路由重定向默认到主页

  • 使用redirect: ' ' 重定向到主页

在这里插入图片描述

import Vue from 'vue'
// 导入使用路由
import Router from 'vue-router'
// 导入刚才编写的组件
import AppIndex from '@/components/home/AppIndex'
import Login from '@/components/Login'

//1.通过Vue.use(插件),安装插件
Vue.use(Router)

//2.创建VueRouter对象,然后把对象传入到vue实例(main.js)。export导出
export default new Router({
  //配置路由和组件之间的关系
  routes: [
    {
      //默认重定向
      path: '',
      redirect:'login'
    },
    {
      //path路径、component被导入的组件的映射、name
      path: '/login',
      name: 'Login',
      component: Login
    },
    {
      path: '/index',
      name: 'AppIndex',
      component: AppIndex
    }
  ]
})


八、路由默认hash模式修改为history模式

  • 使用 mode: 'history',
import Vue from 'vue'
import Router from 'vue-router'
import AppIndex from '@/components/home/AppIndex'
import Login from '@/components/Login'

Vue.use(Router)

export default new Router({
//修改配置为history模式
  mode: 'history',
  routes: [
    {
      path: '/login',
      name: 'Login',
      component: Login
    },
    {
      path: '/index',
      name: 'AppIndex',
      component: AppIndex
    }
  ]
})



九、动态路由

简介:比如在写商品详情页面的时候,页面结构都一样,只是商品id的不同,所以这个时候就可以用动态路由动态

动态路由的官方文档

可以在一个路由中设置多段“路径参数”,对应的值都会设置到$route.params

$route指的是活跃状态下的路由,而不是$router


如何使用动态路由

一般来讲有两种模式
在这里插入图片描述

模式 1

1.先动手试一下上面表格中第一个模式的实现,在我们之前创建的my-first-project的src文件夹下新建一个文件夹并命名为view

然后在文件夹下新建test.vue

在这里插入图片描述

2.打开test.vue文件

在这里插入图片描述
3.到my-project->src->router->index.js文件,打开并输入

在这里插入图片描述
4.再到test.vue组件中输入

在这里插入图片描述

在这里说明一下,$router.params.testId的意思,当然是获取当前路由的参数

6.运行项目,打开浏览器,输入localhost:8080

在这里插入图片描述
以上表格中的第一个模式就完成了,第二个模式同理

模式 2

  1. 修改路由index.js文件
    在这里插入图片描述

2.修改test.vue文件

在这里插入图片描述
3. 启动项目,打开浏览器

在这里插入图片描述


十、路由的懒加载

简介:当打包构建应用时候,JS包会变得非常大,影响页面加载,如果我们能把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候加载就更加高效了。结合 Vue 的异步组件Webpack 的代码分割功能,轻松实现路由组件的懒加载。

问题出现在与:

如果我们一次性在服务器请求下来这个页面,可能需要花费一定的时间,甚至用户访问时候会出现空白的情况,如何避免这个问题就需要路由懒加载(尤其是vue这种单页面应用文件!!!造成进入首页时,需要加载的内容过多)

俗话讲就是:用到时再加载,解决vue第一次加载时间过长的问题


如何使用懒加载

vue-router懒加载的实现非常简单,在配置路由的时候components从原先的写组件名改为resolve => require([URL], resolve)这种格式即可

不使用懒加载写法:

import Vue from 'vue'
import Router from 'vue-router'
import Parent from '@/components/Parent'
 
Vue.use(Router)
 
export default new Router({
  routes: [
    {
      path: '/',
      name: 'Parent',
      component: Parent
    }
  ]
})

使用懒加载写法:

import Vue from 'vue'
import Router from 'vue-router'
 
Vue.use(Router)
 
export default new Router({
  routes: [
    {
      path: '/',
      name: 'Parent',
      component: resolve => require(['@/components/Parent'], resolve)
    }
  ]
})

或者

import Vue from 'vue'
import Router from 'vue-router'

//导入并且懒加载
const Parent =() => import('../components/Parent')
 
Vue.use(Router)
 
export default new Router({
  routes: [
    {
      path: '/',
      name: 'Parent',
      component: Parent
    }
  ]
})

把组件按组分块

有时候我们想把某个路由下的所有组件都打包在同个异步块 (chunk) 中。只需要使用 命名 chunk,一个特殊的注释语法来提供 chunk name (需要 Webpack > 2.4)。

const Foo = () => import(/* webpackChunkName: "group-foo" */ './Foo.vue')
const Bar = () => import(/* webpackChunkName: "group-foo" */ './Bar.vue')
const Baz = () => import(/* webpackChunkName: "group-foo" */ './Baz.vue')

Webpack 会将任何一个异步模块与相同的块名称组合到相同的异步块中。


十一、路由嵌套

简介:就是在一个页面中通过路由嵌套实现访问不同内容。如/home/message和/home/news,可以在同一个页面中切换展示

在这里插入图片描述


如何使用路由嵌套

1. 编写好子组件和主组件
2. 在index.js添加children字段配置映射关系

routes: [
    {
      path: '/',
      name: 'HelloWorld',
      component: HelloWorld,
      //children是拼接上url的
      children: [{path: '/h1', name: 'H1', component: H1},
        {path: '/h2', name: 'H2', component: H2}
      ]
    }
  ]

3.确定routerview好展示位置
在主组件中添加routerview标签

<template>
  <div class="hello">
    <h1>{{ msg }}</h1>
    <router-view></router-view>
  </div>
</template>

4.在主组件中增加链接

<router-link :to="{name:'HelloWorld'}">主页</router-link>
<router-link :to="{name:'H1'}">H1页面</router-link>
<router-link :to="{name:'H2'}">H2页面</router-link>

路由嵌套例子

实际生活中的应用界面,通常由多层嵌套的组件组合而成。同样地,URL中各段动态路径也按某种结构对应嵌套的各层组件,例如:

在这里插入图片描述

如何实现下图效果(H1页面和H2页面嵌套在主页中)?

在这里插入图片描述

1.首先用标签增加了两个新的导航链接

<router-link :to="{name:'HelloWorld'}">主页</router-link>
<router-link :to="{name:'H1'}">H1页面</router-link>
<router-link :to="{name:'H2'}">H2页面</router-link>

2.在HelloWorld.vue加入标签,给子模板提供插入位置

 <template>
  <div class="hello">
    <h1>{{ msg }}</h1>
    <router-view></router-view>
  </div>
</template>

3.在components目录下新建两个组件模板 H1.vue 和 H2.vue。两者内容类似,以下是H1.vue页面内容:

 <template>
  <div class="hello">
    <h1>{{ msg }}</h1>
  </div>
</template>
<script>
  export default {
    data() {
      return {
        msg: 'I am H1 page,Welcome to H1'
      }
    }
  }
</script>

4.修改router/index.js代码,子路由的写法是在原有的路由配置下加入children字段。

   routes: [
    {
      path: '/',
      name: 'HelloWorld',
      component: HelloWorld,
      children: [{path: '/h1', name: 'H1', component: H1},//子路由的<router-view>必须在HelloWorld.vue中出现
        {path: '/h2', name: 'H2', component: H2}
      ]
    }
  ]

十二、router的参数传递

声明式的导航<router-link :to="...">和编程式的导航router.push(...)都可以传参,本文主要介绍前者的传参方法,同样的规则也适用于编程式的导航

name传递参数($route.name)

在路由文件src/router/index.js里配置name属性

routes: [
    {
      path: '/',
      name: 'Hello',
      component: Hello
    }
]

模板里(src/App.vue)用$route.name来接收 比如:<p>{{ $route.name}}</p>,就可以访问该路由页面的时候显示标题


通过<router-link>标签中的:to传参

:to指的是v-blind:to此方法传参传的是一个对象,这种传参方法的基本语法

<router-link :to="{name:xxx,params:{key:value}}">valueString</router-link>

1.比如先在src/App.vue文件中编写对象传参

<router-link :to="{name:'hi1',params:{username:'jspang',id:'555'}}">Hi页面1</router-link>

2.然后把src/router/index.js文件里给hi1配置的路由起个name,就叫hi1

{path:'/hi1',name:'hi1',component:Hi1}

3.最后在模板里(src/components/Hi1.vue)用$route.params.username进行接收.

{{$route.params.username}}-{{$route.params.id}}

利用url传递参数,params类型传参

在这里插入图片描述

我们在/src/router/index.js文件里配置路由

{
    path:'/params/:newsId/:newsTitle',
    component:Params
}

我们需要传递参数是新闻ID(newsId)和新闻标题(newsTitle).所以我们在路由配置文件里制定了这两个值。

在src/components目录下建立我们params.vue组件,也可以说是页面。我们在页面里输出了url传递的的新闻ID和新闻标题。

<template>
    <div>
        <h2>{{ msg }}</h2>
        <p>新闻ID{{ $route.params.newsId}}</p>
        <p>新闻标题:{{ $route.params.newsTitle}}</p>
    </div>
</template>
<script>
export default {
  name: 'params',
  data () {
    return {
      msg: 'params page'
    }
  }
}
</script>

在App.vue文件里加入我们的<router-view>标签。这时候我们可以直接利用url传值了

<router-link to="/params/198/jspang website is very good">params</router-link>


使用path来匹配路由,然后通过query来传递参数

在这里插入图片描述

<router-link :to="{ name:'Query',query: { queryId:  status }}" >
     router-link跳转Query
</router-link>

对应路由配置:

   {
     path: '/query',
     name: 'Query',
     component: Query
   }

于是我们可以获取参数:

this.$route.query.queryId

什么是query和完整url

在这里插入图片描述

一个完整的URL=协议+域名+端口号+路径+资源+搜索词+哈希

# 传输协议是用来完成客户端和服务器端之间数据传输的
# 传输协议可分为三类

1.http:超文本传输协议
2.https:http ssl,它比http更加安全
3.ftp:资源文件传输协议
# 问号传参(可有可无)
把一些值通过 “key=value” 的方式放在一个URL的末尾,通过?传递;

作用:
1、在ajax请求中,我们可以通过问号传递参数的方式,在客户端把一些信息传递给服务器,服务器根据传递信息的不一样,返回不同的数据;
2、清除ajax get方法的缓存,?math_random=0.123456;
3、通过URL传递参数的方式,实现页面之间的通信;
HASH值(可有可无)
作用

1、可做页面中的锚点定位

2、在单页应用开发中作为前端路由使用(Vue Router、React Router);

—end

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值