说到路由, 我们最熟悉的路由是什么呢? 那就是路由器了。 其实路由器有两个重要的功能: 路由和传送
- 路由: 路由决定数据包从哪里来, 到哪里去。 也有是来源和目的地的路径。
路由中有一个路由表,路由表本质上就是一个映射表,决定了数据包的传输方向。
- 传送: 传送是将输入端的数据传送给输出端
下面我们先来搭建一个项目, 然后一边学习一遍在项目里实战
创建vue-cli2项目
vue init webpack vueroute
然后一路向下就可以了, 如果本地创建项目很慢, 可以采用离线创建项目的方式, 具体步骤:
1. 下载webpack离线模板: https://github.com/vuejs-templates/webpack
2. 将下载的模板压缩包解压,修改文件名为wepback并放入到/Users/自己电脑的用户名/.vue-templates文件夹中.
3. 执行创建项目的命令: vue init webpack --offline
一、前后端路由的来历
- 前后端路由, 目前经历了三个阶段, 哪三个阶段呢?
前后端一体(后端路由)阶段: 这个阶段类似早起的jsp页面, 和java页面混合在一起, jsp里面有css, js, 还有java代码, 前后端都是混合在一起的。
缺点很明显, 前后端分工不明确.
这种方式采用的是后端路由
基本流程: 请求一个controller接口 --> 通过接口找到页面 --> 渲染页面 --> 返回给浏览器
- 前后端分离阶段: 前端通过ajax调用的形式, 调用后台接口. 前端主要负责页面渲染, 后端主要提供api接口。
优点: 前后端分离. 各司其职, 分明明确. API可复用性强, fe, android, ios都可用
此时用户请求的就是一个html页面, 页面需要哪个url了, 直接通过ajax请求到页面。
基本流程: 浏览器url请求 -> html页面 -> ajax请求api接口 -> 后台接口响应数据 -> html页面渲染 -> 返回给浏览器
- 单页面富应用阶段: 简称SPA, 全称是simple page application. 最主要的特点是在前后端分离的基础上加了一层前端路由. 这个路由是有前端来维护的一套路由。
单页面指的是:一个html文件 + 一个js文件 + 一个css文件。
可是就一个网站来说, 不可能只有一个页面. 那么是如何实现的呢?我们来看下图:
前端只有一个页面index.html, 而各个功能都是一个组件, 将所有组件都放到index.html页面中, 然后根据用户的请求定位到某一个组件. 这个是谁来定位的呢?就是前端路由来定位, 在vue中前端路由就是vue-router。
前端路由的核心是什么呢? 改变url, 但是页面不进行整体刷新。
二. 前端如何实现页面跳转但是不刷新?
前面说了, vue使用的是单页面富应用, 也就是一个index.html就是整个项目, 然后在内部在跳转链接的时候, 不会刷新页面, 实现这种方式有两种方法:hash和history
这两种模式都可以实现页面跳转,但是不刷新页面. 他们如何使用, 又有什么区别呢?
1. hash
首先启动vue项目
vue init dev
然后打开页面
localhost:8080
在浏览器控制台输入localhost.hash=“about”, 我们可以看到页面链接变成了localhost:8080/#/about/
如上图, 我们可以通过location.hash="链接"的方式来修改url,但是并不刷新页面
2. history
除了使用hash,我们还可以使用history来改变实现改变url但不刷新页面的方法. history有几个常见的用法。
- history.pushState(state,“title”,“url”)
向浏览器新增一条历史记录,但是不会刷新当前页面(不会重载)
- state为对象,可以用作携带信息用,
- title:目前来看没啥用一般为空或null,
- URL:即要更改页面的URL,且必须同源,不能跨域;
案例: 我们在vue的浏览器界面改变http://localhost:8080为http://localhost:8080/about
如上图所示: 当我们执行history.pushState({a:1},null,“about”);的时候, 浏览器并没有刷新页面(Network没有请求), 但是url链接确实发生了变化
- history.replaceState(state,title,URL)
更改当前浏览器的历史记录,即把当前执行此代码页面的记录给替换掉,参数与第一条相同
- history.back()、history.forward()、history.go()
分别为前进一个历史,后退一个,history.go(Number),其中Number可正可负,即向前或向后若干个记录
案例:
如上图, 当我们使用history.back()命令的时候, 会回退到上一个页面, 也并没有发生更新。
- history.state
返回当前页面状态参数,此参数一般由history.pushState(state,title,URL);以及history.replaceState(state,title,URL);附带的state值,例子如下:
案例:
如上图: 可以看出history.state就是取出了pushState和replaceState两个命令中的第一个参数
- history.length
返回当前页面所产生的历史记录个数,即在同一个浏览器tab下产生的历史记录;- history事件onpopstate
window.onpopstate = function(e){
console.log(e.state);
}
在history.back(),history.forward(),history.go()时触发此事件,但是在history.pushState();history.replaceState();时并不会触发此事件,事件内可以获取到state状态值
可以看出vue-router中push()、go()等函数是基于hash和histroy的,但是vue-router比这个要复杂。
三、 vue-router基本使用
vue-router是Vue.js官方的路有插件, 他和vue.js是深度集成的.适合构建于单页面富应用。
vue-router官网: https://router.vuejs.org/zh/
- vue-router是基于路由和组件的: 路由用于设定访问路径, 将路径和组件映射起来
- 在vue-router的单页面应用中, 页面的路径的改变就是组件的切换
1、安装vue-router
npm install vue-router --save
–save: 表示在构建以后也要使用这个路由
安装好以后, 在package.json中就可以看到安装的vue-router的版本了
并且在src目录下多了一个文件夹router
2、搭建vue-router框架的步骤
在我们安装了vue-router以后,就会在src目录下自动生成一个文件夹router.
我们在里面创建一个index.js文件, 然后开始配置路由相关的信息
- 第一步: 导入路由对象,并且调用vue.use(VueRouter) 安装了vue-router, 要想使用, 还需要先引入路由对象
import Router from 'vue-router'
vue-router是一个插件, 所以, 我们需要使用vue.use(插件名) 来安装插件
Vue.use(Router)
- 第二步: 创建路由实例,并且传入路由映射配置
在VueRouter中主要是配置路由和组件之间的映射关系的。
const routes = [
]
const router = new VueRouter({
// 这里配置的是路由和组件的映射关系, 是一个数组.
routes
})
在这里路由是空的, 还没有配置任何映射关系。
- 第三步: 将vue-router实例对象导出
export default router
- 第四步: 在vue实例中挂载创建的路由实例
import router from './router'
在import目录的时候, 有一个默认的规则, 那就是如果你导入一个目录, 比如./router, 没指定导入哪一个文件, 他会自动导入index.js文件
然后在vue实例中引入router
new Vue({
el: '#app',
// 然后通过router导入vue路由
router,
render: h => h(App)
})
3、 vue-router路由的配置步骤
-
第一步: 创建路由组件
通常, 我们会在components目录下创建组件。鼠标右击-> Vue Component, 然后定义组件内容
我们创建两个组件, 一个首页, 一个关于页面。首页
<template>
<div>
<h2>这是Home主页</h2>
<div>欢迎来到home主页</div>
</div>
</template>
<script>
export default {
name: "Home"
}
</script>
<style scoped>
</style>
关于页面
<template>
<div>
<h2>关于页面</h2>
<div>欢迎来到关于页面</div>
</div>
</template>
<script>
export default {
name: "About"
}
</script>
<style scoped>
</style>
这样组件就创建好了。
- 第二步: 配置路由映射。 即:组件和路由的关系
组件创建好了, 接下来要构建组件和路由的关系。 构建路由关系,我们通常定义在router/index.js文件
映射关系主要有两个部分. 一个是path:路由的路径; 一个是component:关联的组件
在router/index.js文件中首先引入上面定义好的组件
import Home from '../components/Home';
import About from "../components/About";
然后指定路由路径和组件
const routes = [
{
path: "/home",
component: Home
},{
path: "/about",
component: About
}
]
- 第三步: 使用路由, 通过和来展示组件
现在组件有了, 路有关系也有了。 那么接下来就是要有个入口来展示组件或者路由了。 我们的入口只有一个, 那就是App.vue, 所以, 我们直接在这里定义两个入口即可。
<template>
<div id="app">
<!-- 定义两个路由链接 -->
<router-link to="/home">首页</router-link>
<router-link to="/about">关于</router-link>
<!-- 展示组件内容 -->
</router-view>
</template>
: 是一个vue-router中内置的组件, 它会被渲染成一个a标签。
: 会根据当前的路径, 动态渲染组件的内容
网页的其他内容, 例如:顶部的标题/导航,底部的版权信息等和/处于一个等级
在切换路由时, 切换的是挂在组建的内容, 其他不会发生改变
整体效果如下:
4、路由的默认配置
现在我们进入首页显示的只有导航信息, 在页面必须点击某一个按钮,才能渲染出对应组件的内容。通常我们会有一个默认组件的展示。 否则首页内容就是空的了。如何设置默认展示的路由呢?
在路由表中增加一个重定向路由
{
path:"/",
redirect: "/home"
}
这样, 打开首页,直接加载home组件的内容
5. 修改静态路由的模式为history
我们之前都是采用hash的方式来静态路由跳转的, 但hash方式有一个缺点, 即带有#
例如:我们跳转都Home页, 他的路径是
http://localhost:8080/#/home
带有一个#, 这不符合我们通常路径的使用方法,所以,我们可以考虑将其替换为history的模式。 如何替换呢? 在router/index.js文件中
const router = new Router({
// 这里配置的是路由和组件的映射关系, 是一个数组.
routes,
mode: "history"
})
- vue-link属性设置
- to属性
我们在首页, 定义vue-link跳转的路由使用的就是to属性
<template>
<div id="app">
<!-- 定义两个路由链接 -->
<router-link to="/home">首页</router-link>
<router-link to="/about">关于</router-link>
<!-- 展示组件内容 -->
</router-view>
</template>
- tag属性
默认会被渲染成a标签, 如果我们想要将其渲染为其他标签是否可以呢? 当然是可以的, 使用tag属性, 比如: 我们想要将其渲染为button标签
<template>
<div id="app">
<!-- 定义两个路由链接 -->
<router-link to="/home" tag="button">首页</router-link>
<router-link to="/about" tag="button">关于</router-link>
<!-- 展示组件内容 -->