1. 后端路由阶段
早期的网站开发整个
HTML
页面是由服务器来渲染的。服务器直接生产渲染好对应的HTML页面, 返回给客户端进行展示。
1.1 但是, 一个网站, 这么多页面服务器如何处理呢?
一个页面有自己对应的网址, 也就是
URL
。URL
会发送到服务器, 服务器会通过正则对该URL
进行匹配, 并且最后交给一个Controller
进行处理。Controller
进行各种处理, 最终生成HTML
或者数据, 返回给前端。这就完成了一个
IO
操作。
上面的这种操作, 就是后端路由,当我们页面中需要请求不同的路径内容时, 交给服务器来进行处理, 服务器渲染好整个页面, 并且将页面返回给客户端,这种情况下渲染好的页面, 不需要单独加载任何的
js
和css
, 可以直接交给浏览器展示, 这样也有利于SEO
的优化。
1.2 后端路由的缺点:
一种情况是整个页面的模块由后端人员来编写和维护的;
另一种情况是前端开发人员如果要开发页面, 需要通过
PHP
和Java
等语言来编写页面代码;而且通常情况下HTML代码和数据以及对应的逻辑会混在一起, 编写和维护都是非常糟糕的事情。
2. 前端路由阶段
2.1 前后端分离阶段
随着
Ajax
的出现, 有了前后端分离的开发模式。后端只提供
API
来返回数据, 前端通过Ajax
获取数据, 并且可以通过JavaScript
将数据渲染到页面中。这样做最大的优点就是前后端责任的清晰, 后端专注于数据上, 前端专注于交互和可视化上。
并且当移动端
(iOS/Android)
出现后, 后端不需要进行任何处理, 依然使用之前的一套API
即可。
2.2 单页面富应用阶段
其实SPA最主要的特点就是在前后端分离的基础上加了一层前端路由。
也就是前端来维护一套路由规则。
3. URL的hash 模式 和 HTML5 的 history 模式
3.1 URL的hash模式
-
URL
的hash
也就是锚点(#
), 本质上是改变window.location
的href
属性;我们可以通过直接赋值location.hash
来改变href
, 但是页面不发生刷新。
3.2 HTML5的history模式
-
history
对象的pushState
方法传递三个参数,第一个参数是一个对象。第二个参数是title
, 第三个参数是路径。
-
history
模式的replaceState
方法:替换路径,不能通过返回箭头返回。
-
history
模式的go
方法:到某个索引的路径下:
history.go(-1) // 表示后退一步 和 history.back() 类似
history.go(1) // 表示前进一步 和 history.forward() 类似
4. Vue-Router的安装配置
- Vue-router是
Vue.js
官方的路由插件,它和
4.1 安装 Vue-Router
- 安装为一个运行时依赖:
npm install vue-router --save
创建一个
router
文件夹,并在文件中创建一个index.js
文件。在
index.js
文件中引入VueRouter
对象和Vue
对象。
import VueRouter from 'vue-router';
import Vue from 'vue';
- 通过Vue.use(传入插件)安装该插件,任何Vue的插件都要使用 Vue.use进行安装。
Vue.use(VueRouter);
- 创建
VueRouter对象实例
,注意这里是 routes 而不是 routers 重要重要重要
// 路由数组
const routes = [];
// 2. 创建VueRouter对象
const router = new VueRouter({
// 配置组件之间的映射关系
// 对象属性的简写
routes
});
- 导出
VueRouter
对象实例:
export default router;
- 在
main.js
中引入并使用router
:
4.2 配置路由的映射关系
- 在
components
文件夹下创建Home
和About
组件。
- 在
router/index.js
下配置路由映射关系 。
- 使用
Vue
中注册的全局组件router-link
和router-view
实现页面跳转和渲染。
首页
关于
: 该标签会根据当前的路径, 动态渲染出不同的组件。默认显示首页:
/home
,将进入页面时将页面重定向到Home
页面
// 路由数组
const routes = [
{
path: '/',
/* 将路径重定向到home */
redirect: '/home'
},
{
path: '/home',
name: 'Home',
component: Home
},
{
path: '/about',
component: About
}
]
4.3 修改路由的模式为 history
- 默认情况下,路径改变使用的是
URL
的hash
,如果希望使用HTML5
的history
模式可以进行如下的修改。
// 2. 创建VueRouter对象
const router = new VueRouter({
// 配置组件之间的映射关系
// 对象属性的简写 但是这个属性必须交 routes
routes,
mode:'history'
});
4.4 router-link 的其他属性
router-link
标签的 tag
属性
- 可以 通过
tag
设置router-link
使用什么标签来进行渲染。
首页
关于
router-link
标签的 replace
属性
-
replace
属性设置之之后通过该标签跳转的路径,不能通过浏览器的后退键返回。replace
不会留下history
记录, 所以指定replace
的情况下, 后退键返回不能返回到上一个页面中。这就说明vue-router
默认使用的是history
的pushState
。
首页
关于
router-link
标签的 active-class
属性
- 默认情况下当点击某个标签,该标签被激活之后,在其中会添加一个
class
,router-link-active
。可以通过该class
设置激活样式。
.router-link-active {
color: #f00;
}
- 该
class
的名称是可以被修改的,此时就需要在标签中 使用active-class
属性对class
的名称进行修改。
首页
关于
.active {
color: #00f;
}
在 router/index.js
文件的router
对象中使用linkActiveClass
属性统一修改样式名称
4.5 通过代码实现路由的跳转
- 在页面中定义两个按钮实现路由的跳转:利用
vue
内置的$router
的push
和replace
方法实现跳转。
/**
* 跳转到 首页
*/
btnClickHome() {
// this.$router.push('/home');
this.$router.replace('/home'); // 跳转之后不能通过浏览器的后退按钮返回
},
/**
* 实现跳转到关于
*/
btnClickAbout() {
// this.$router.push('/about');
this.$router.replace('/about'); // 跳转之后不能通过浏览器的后退按钮返回
}
5. vue-router 动态路由的使用
- 创建一个
User
组件并在router/index.js
中配置路由:
// 路由数组
const routes = [
{
path: '/',
/* 将路径重定向到home */
redirect: '/home'
},
{
path: '/home',
name: 'Home',
component: Home
},
{
path: '/about',
component: About
},
{
path: '/user/:userId',
component: User
}
];
- 在
APP.vue
中使用router-link
配置路由实现跳转:在配置时一并传递参数。
首页
关于
用户
- 在跳转到
User
组件之后,在User
页面获取到路径中的userId
参数:这里需要通过一个$route
的属性获取。使用$route.params.userId
获取。但是这里的userId
是与路由配置中的userId
一一对应的。
我是User组件
{{$route.params.userId}} 您好!
{{userId}} 您好!
computed: {
userId() {
return this.$route.params.userId
}
}
6. vue-router 打包文件的解析
7. 路由的懒加载
路由懒加载的官方解释:首先, 我们知道路由中通常会定义很多不同的页面,这个页面最后被打包在哪里呢? 一般情况下, 是放在一个
js
文件中,但是, 页面这么多放在一个js
文件中, 必然会造成这个页面非常的大,
如果我们一次性从服务器请求下来这个页面, 可能需要花费一定的时间, 甚至用户的电脑上还出现了短暂空白的情况。路由懒加载做了什么? 答: 路由懒加载的主要作用就是将路由对应的组件打包成一个个的
js
代码块。只有在这个路由被访问到的时候, 才加载对应的组件。
7.2 各种路由懒加载的配置方式
- 方式一: 结合
Vue
的异步组件和Webpack
的代码分析
const Home = resolve => { require.ensure(['../components/Home.vue'], () => { resolve(require('../components/Home.vue')) })};
- 方式二:
AMD
写法
const About = resolve => require(['../components/About.vue'], resolve);
- 方式三: 在
ES6
中, 我们可以有更加简单的写法来组织Vue
异步组件和Webpack
的代码分割
const Home = () => import('../components/Home.vue')
8. 认识路由的嵌套
8.1 嵌套路由配置案例
- 创建一个
HomeMessage
和HomeNews
组件。
- 消息1
- 消息2
- 消息3
- 消息4
- 新闻1
- 新闻2
- 新闻3
- 新闻4
- 配置嵌套路由 :
/* 使用懒加载的方式加载组件 */
const Home = () => import('../components/Home')
const HomeNews = () => import('../components/HomeNews')
const HomeMessage = () => import('../components/HomeMessage')
const About = () => import('../components/About')
const User = () => import('../components/User')
// 1. 通过Vue.use(传入插件)安装该插件,任何Vue的插件都要使用 Vue.use进行安装
Vue.use(VueRouter);
// 路由数组
const routes = [
{
path: '/',
/* 将路径重定向到home */
redirect: '/home'
},
{
path: '/home',
name: 'Home',
component: Home,
/* 配置路由的嵌套 */
children:[
/* 配置默认显示首页的时候一并显示消息 */
{
path:'/',
redirect:'news'
}
,
{
/* 注意这里没有 斜杠 / 这里是不能有 斜杠的 */
path:'news',
component:HomeNews
},
{
path:'message',
component:HomeMessage
}
]
},
{
path: '/about',
component: About
},
{
path: '/user/:userId',
component: User
}
];
- 因为这两个组件需要在
Home
组件中切换显示,所以还需在Home
组件中使用router-link
和router-view
进行配置。
我是Home组件
新闻
消息
9. vue-router 参数传递
9.1 参数传递的方式一 user/:userId
9.2 参数传递的方式二 query参数对象传递案例
- 创建一个新的组件
Profile
我是Profile组件
- 为组件配置路由 :
- 使用
router-link
的方式实现路由的跳转并传递query
参数对象。
- 使用触发事件的方式实现路由的跳转:通过
this.$router.push(``)
的方式实现路由跳转。
10. vue-router 和 vue-route 是由区别的
$router
为VueRouter
实例,想要导航到不同URL
,则使用$router.push
方法。$route
为当前router
跳转对象里面可以获取name、path、query、params
等。
11. 导航守卫
1.有时可能需要在跳转过程之间做一些新的操作。就可以使用导航守卫监听跳转过程。
- URL组成:
URL= scheme(协议)://host(主机):port(端口)/path(路径)?query(查询)#fragment(片段)
;
11.1 当页面跳转的时候如果需要改变 title 该如何做?
网页标题是通过
来显示的, 但是SPA
只有一个固定的HTML
, 切换不同的页面时, 标题并不会改变。但是我们可以通过
JavaScript
来修改
的内容window.document.title = '新的标题'
。
- 那么在
Vue
项目中, 在哪里修改? 什么时候修改比较合适呢?
使用导航守卫在路由跳转前进行修改页面 title
操作
使用
router
实例对象的beforeEach
方法前置守卫函数,函数中传递一个钩子函数,钩子函数需要 3 个参数。to , from ,next
。需要向下执行就需要调用next()
。在执行
next()
之前将title
进行修改。但是动态的title
从哪里来呢?
11.2 导航守卫的分类
全局路由守卫;
路由独享守卫;
组件内守卫。
参考。
12. vue-router 的 keep-alive
-
keep-alive
是一个标签,是一个保持组件为活跃状态,不会被频繁的创建和频繁的销毁。
12.1 利用 keep-alive 和 activated 、beforeRouteLeave 导航守卫实现记住上一个页面的选择案例
- 当
router-view
标签外面包裹了keep-alive
标签之后activated
方法就会有效:在该方法中实现路由的跳转。
- 当离开当前的组件之前记录一下当前的路径
path
。
只有使用 keep-alive标签包裹的组件使用 activated 和 deactived 才是有效的。
12.2 keep-alive的其他属性
keep-alive
是 Vue
内置的一个组件,可以使被包含的组件保留状态,或避免重新渲染。
include
: 字符串或正则表达,只有匹配的组件会被缓存;exclude
: 字符串或正则表达式,任何匹配的组件都不会被缓存;