文章目录
1.前言
之前说了vue-cli系列,已经清楚了目录结构,还有webpack的配置,那么下面几篇文章我们来说下vue-router!
2.什么是单页面应用(SPA)
单页Web应用(single page web application)是一种特殊的Web应用,是加载单个 HTML 页面并在用户与应用程序交互时动态更新该页面的,因为是单页面只有一个页面的应用,所以一开始只需加载一次 js,css 等相关资源。所有的内容都包含在主页面,对每一个功能模块组件化。单页应用跳转,就是切换相关组件,仅刷新局部资源,它都有什么优点和缺点?
3.单页面应用(SPA)优缺点?
优点:
1. 有良好的交互体验(能提升页面切换体验,用户在访问应用页面是不会频繁的去切换浏览页面,从而避免了页面的重新加载)
2. 前后端分离开发(单页Web应用可以和 RESTful 规约一起使用,通过 REST API 提供接口数据,并使用 Ajax 异步获取,这样有助于分离客户端和服务器端工作。更进一步,可以在客户端也可以分解为静态页面和页面交互两个部分)
3. 减轻服务器压力(服务器只用出数据就可以,不再负责模板渲染、输出页面工作)
4. 共用一套后端程序代码(不用修改后端程序代码就可以同时用于 Web 界面、手机、平板等多种客户端,后端API通用化)
缺点:
1. SEO难度较高(由于所有的内容都在一个页面中动态替换显示,所以在SEO上其有着天然的弱势,所以如果你的站点对SEO很看重,且要用单页应用,那么就做些静态页面给搜索引擎用吧)
2. 前进、后退管理(由于单页Web应用在一个页面中显示所有的内容,所以不能使用浏览器的前进后退功能,所有的页面切换需要自己建立堆栈管理,当然此问题也有解决方案,比如利用URI中的散列+iframe实现)
3. 初次加载耗时多(为实现单页Web应用功能及显示效果,需要在加载页面的时候将JavaScript、CSS统一加载,部分页面可以在需要的时候加载。所以必须对JavaScript及CSS代码进行合并压缩处理)
4.单页面应用(SPA)和vue-router关系?
单页面应用的核心技术就是前端路由,我们可以通过管理url,实现url和组件的对应和用通过url进行组件之间的切换
5.前端路由的两种模式
5.1 hash路由
它是地址栏 URL 中的 # 符号,比如https://blog.csdn.net/ws9029#/home,那么hash的值为 #/home,hash 虽然出现在 URL 中,但不会被包括在 HTTP 请求中,对后端完全没有影响,因此改变 hash 不会重新加载页面,路由的哈希模式其实是利用了window.onhashchange事件,也就是说你的url中的哈希值(#后面的值)如果有变化,就会自动调用hashchange的监听事件,在hashchange的监听事件内可以得到改变后的url,这样前端并没有发起http请求他也能够找到对应页面的代码块进行按需加载!下面来简单的模拟一下!
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
</head>
<body>
<ul>
<li>
<a href="#/a">a</a>
</li>
<li>
<a href="#/b">b</a>
</li>
<li>
<a href="#/c">c</a>
</li>
</ul>
<div id="view"></div>
<script>
let view = document.querySelector('#view');
// 监听hash变化
window.addEventListener('hashchange', viewChange);
// 渲染视图
function viewChange() {
switch (location.hash) {
case '#/b':
view.innerHTML = 'b';
break;
case '#/c':
view.innerHTML = 'c';
break;
default:
view.innerHTML = 'a';
break;
}
}
</script>
</body>
</html>
当我点击一个a元素后,hash值就会发现变化,然后调用viewChange事件把相对应的内容刷新到页面的id为view的div元素上
5.2 history路由
利用了 HTML5 History 中的 pushState() 和 replaceState() 方法,用来完成 URL 跳转而无须重新加载页面,不过这种模式还需要后台配置支持。因为我们的应用是个单页客户端应用,如果后台没有正确的配置,就需要前端自己配置404页面。只有前后端联手,才能天衣无缝!另外,pushState方法,replaceState方法,只能导致history对象发生变化,从而改变当前地址栏的 URL,但浏览器不会向后端发送请求,也不会触发popstate事件的执行,popstate事件的执行是在点击浏览器的前进后退按钮的时候(back、forward、go),才会被触发!我们来简单的模拟一下!
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
</head>
<body>
<ul>
<li>
<a href="/a">a</a>
</li>
<li>
<a href="/b">b</a>
</li>
<li>
<a href="/c">c</a>
</li>
</ul>
<div id="view"></div>
<script>
var view = null;
view = document.querySelector('#view');
document.querySelectorAll('a[href]').forEach(item => item.addEventListener('click', function (event) {
event.preventDefault();
history.pushState(null, '', item.getAttribute('href'));
viewChange();
}));
// 监听路由变化
window.addEventListener('popstate', viewChange);
// 渲染视图
function viewChange(event) {
switch (location.pathname) {
case '/b':
view.innerHTML = 'b';
break;
case '/c':
view.innerHTML = 'c';
break;
default:
view.innerHTML = 'a';
break;
}
}
</script>
</body>
</html>
history路由主要原理是点击a标签,一般点击a标签,默认会跳转页面,所以必须先要阻止a标签的默认事件,获取到a标签的path,用过一些路由的api匹配到对应的path然后渲染对应的组件到页面上,
5.3 路由总结
两种路由,都有各自的优缺点,hash路由看上去多个#号,看起来很丑,在有些第三方的app里面url是不允许带有#号的,但是它刷新毫无压力,可以加载到hash对应的页面,并且兼容性比较好,可以支持比较低版本的浏览器,history看上去像正面的页面地址,并且设置的新URL可以是与当前URL同源的任意URL,甚至可以与当前URL一模一样(hash只能设置与当前同文档的URL),history的pushState通过stateObject可以添加任意类型的数据到记录中,并且还可以设置title属性(hash只可添加短字符串),但是要是刷新的话,需要前后端配合,因为history并没有去请求服务器该路径下的资源,一旦刷新就会挂了,所以需要后端将不存在的路径请求重定向到入口文件index.html!