从代码分析,从头构建一个vue项目需要理解vue的各个知识点。
当你使用npm创建一个vue项目之后,首先接触的就是app.vue。该文件的内容也很简单,最开始就是如下:
从这里就可以看到<router-view/>
而这个就是大名鼎鼎的前端路由,可以知道,凡是整个项目都是DOM直出的页面,我们都称它为“传统页面”(SSR 属于首屏直出,这里我不认为是传统页面的范畴)。那么什么是DOM直出呢?
简单说就是在浏览器输入网址后发起请求,返回来的HTML页面是最终呈现的效果,那就是DOM直出。并且每次点击页面跳转,都会重新请求HTML资源。
说的更简单一点就是你去查看一些网页开发者模式,查看以下network请求返回的的资源 如果是页面资源除了css跟script文件以外 全部都有,那么就是传统的DOM直出。
而随着对网页需求的不断增高,网页也越来越倾向转为模块化、组件化的道路。而顺势而生的React、 Vue、 Angular 等著名单页面应用框架。而这些框架有一个共同的特点,便是“通过 JS 渲染页面”。
这些单页面框架之后, HTML页面基本上只有一个 DOM 入口,大致如下所示:
所有的页面组件,都是通过运行上图底部的 app.js脚本,挂载到 <div id="root"></div> 这个节点下面。用一个极其简单的 JS 展示挂载这一个步骤:
既然单页面是这样渲染的,那如果我有十几个页面要互相跳转切换,咋整!!??这时候 前端路由 应运而生,它的出现就是为了解决单页面网站,通过切换浏览器地址路径,来匹配相对应的页面组件。
简单来说下逻辑就是:
http://192.168.12.216:8080/#/中国---->定位到 /中国 ----->跳转到中国这个组件
http://192.168.12.216:8080/#/美国---->定位到 /美国----->跳转到美国 这个组件
前端路由 会根据浏览器地址栏 pathname 的变化,去匹配相应的页面组件。然后将其通过创建 DOM 节点的形式,塞入根节点 <div id="root"></div> 。这就达到了无刷新页面切换的效果,从侧面也能说明正因为无刷新,所以 React 、 Vue 、 Angular 等现代框架在创建页面组件的时候,每个组件都有自己的 生命周期 。
这里终于说到我们的Vue-Router
为了让大家对前端路由的原理有一个更深刻的理解,我们来通过分析哈希模式和历史模式的实现原理来帮助大家明白前端路由是怎么实现的。
哈希模式
a标签锚点大家应该不陌生,而浏览器地址上#后面的变化,是可以被监听的,浏览器为我们提供了原生监听事件hashchange,它可以监听到如下的变化:
点击a标签,改变了浏览器地址
浏览器的前进后退行为
通过window.location方法,改变浏览器地址
历史模式
history 模式会比 hash模式稍麻烦一些,因为 history模式依赖的是原生事件 popstate,下面是来自 MDN 的解释:
需要注意的是调用history.pushState()/history.replaceState()不会触发popstate事件。只有在做出浏览器动作时,才会触发该事件,如用户点击浏览器的回退按钮(javaScript代码中调用history.back()/history.forward())
tips:pushState 和 replaceState 都是 HTML5 的新 API,他们的作用很强大,可以做到改变浏览器地址却不刷新页面。这是实现改变地址栏却不刷新页面的重要方法。
因为a标签点击事件并不受到popState监听,所以我们必须想方法组织a标签的默认事件,加上点击事件的回调函数,在回调函数内获取 a 标签的 href属性值,再通过 pushState 去改变浏览器的 location.pathname 属性值。然后手动执行 popstate 事件的回调函数,去匹配相应的路由。
以上这段没理解也没事,因为后面会针对vue项目中如何丝滑的使用路由进行详解。