前端路由 router 原理及表现

原始时代路由

路由全部都是由服务端控制的,前端代码和服务代码过度融合在一起。
客户端/前端发起http请求,服务端通过不同的url路径去匹配不同的路由/返回不同的数据
优点:直接返回一个html文档,渲染页面结构。SEO效果很好,首屏时间快
缺点: 前端代码和服务代码融合在一起,开发协同非常混乱。服务器压力大,因为把构建html的工作放在服务端。

单页面应用

所谓的单页面是指只有一个html 文档。
特点:

  1. 页面中的交互是不刷新页面的,比如点击按钮,比如点击出现一个弹窗
  2. 多页面间的交互不需要刷新页面,比如跳转
  3. 加载过的公共资源无需重复加载
  4. 不同url 会渲染不同内容

Hsah 与History

  1. 直观上看 hash路由有#,history 路由没有
  2. hash 的#部分内容不会给服务端,history 路由的所有内容都会给服务端
  3. hash 通过hashchange 监听变化,history 通过 popstate 监听变化

Hsah

特点

  1. url 中带有#号, # 后面的部分不会传递给服务端
    举个例子 www.XXX.com/#/uder/xiaoming 服务器只能拿到 www.XXX.com/
  2. hash 值得更改不会导致页面刷新
    location.hash = '#user' 改为 location.hash = '#home'
    html 文档不会刷新
  3. hash 值得更改,会在浏览器的访问历史中添加一条记录,所以我们才可以通过浏览器的返回、前进按钮来控制hash的切换
  4. hash 值得更改会触发hashchange 事件
    location.hash = '#user' 改为 location.hash = '#home' 可以通过
    window.addEventLisenter('hashchange',()=>{})监听

如何更改hash

  1. location.hash="#xiaoming"
  2. html 标签样式 <a href="#xiaoming" >点击跳转到xiaoming</a>

html5 history

window.history.back() // 后退
window.history.forward() // 前进
window.history.go() // 可传一个number ,正值前进 负值后退
window.history.pushState(null,null,null)
window.history.replaceState(null,null,null)

pushState/replaceState 的参数

  1. state 是一个对象与指定网址相关,当popstate 事件触发的时候该对象会传入回调函数
  2. title 新页面的标题,浏览器支持不一,null
  3. url 页面新地址

History 的特性

pushState时会触发popState 吗?

  1. 没有#
  2. pushState/replaceState 并不会触发 popstate 事件, 这时我们需要手动触发页面的重新渲染。
  3. 我们可以使用 popstate 来监听 url 的变化
  4. popstate 到底什么时候才能触发。
    4.1 点击浏览器后退按钮
    4.2 点击浏览器前进按钮
    4.3 js 调用 back 方法
    4.4 js 调用 forward 方法
    4.5 js 调用 go 方法

手写一个hashRouter 简易版

class BaseRouter{
    constructor(){
        this.routes = {}
        this.refresh = this.refresh.bind(this);
        window.addEventListener('load', this.refresh); 
        window.addEventListener('hashchange', this.refresh); 
    }
    router(path,callback){
        this.routes[path] = callback || function(){}
    }
    refresh(){
        const path = `/${location.hash.slice(1) || '' }`
        this.routes[path]();
    }

}


let body = document.querySelector('body')

function changeBgColor(color){
    body.style.backgroundColor= color
}

const Router = new BaseRouter()
Router.router('/',function(){
    changeBgColor('white')
})
Router.router('/green',function(){
    changeBgColor('green')
})
Router.router('/gray',function(){
    changeBgColor('gray')
})

手写一个historyRouter 简易版

class BaseRouter{
    constructor(){
        this.routers = {}
        this.init(location.pathname)
        this._bindPopState()
    }
    init(path){
        window.history.replaceState(path,null,path)
        const cb = this.routers[path] 
        cb && cb()
    }
    router(path,callback){
        this.routers[path] = callback || function(){}
    }
    _bindPopState(){
        window.addEventListener('popsate',(e)=>{
            const path = e.state && e.state.path
            this.routers[path] && this.routers[path]()
        })
    }
    go(path){
        window.history.pushState({path},null,path)
        const cb = this.routers[path]
        cb && cb()
    }
   
}


let body = document.querySelector('body')
const container = document.querySelector('.container');
function changeBgColor(color){
    body.style.backgroundColor= color
}

const Router = new BaseRouter()
Router.router('/',function(){
    changeBgColor('white')
})
Router.router('/green',function(){
    changeBgColor('green')
})
Router.router('/gray',function(){
    changeBgColor('gray')
})
container.addEventListener('click',(e)=>{
    if(e.target.tagName === 'A'){
        e.preventDefault()
        Router.go(e.target.getAttribute('href'))
    }
})

historyRouter 需要后端配合,将路由映射地址改为index.html

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,922评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,591评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,546评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,467评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,553评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,580评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,588评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,334评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,780评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,092评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,270评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,925评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,573评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,194评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,437评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,154评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,127评论 2 352

推荐阅读更多精彩内容

  • 关于路由 路由其实是根据不同的URL地址展示不同的内容或页面;广义上来说,访问路由会映射到相应的函数里,然后由相应...
    hellomyshadow阅读 1,953评论 0 0
  • vue-router 中常用的 hash 和 history 路由模式实现原理吗? Two Point!!! sp...
    斗伽阅读 531评论 4 9
  • 通常 SPA 中前端路由有2种实现方式: window.history location.hash 下面就来介绍下...
    好奇男孩阅读 1,172评论 0 18
  • 前言开门见山,这篇文章,适合 「 初级前端 」 ,如果你还在校招的话,或者还在求职的话,可以看看本文,找一找灵感,...
    WEB前端含光阅读 1,343评论 1 2
  • 我是黑夜里大雨纷飞的人啊 1 “又到一年六月,有人笑有人哭,有人欢乐有人忧愁,有人惊喜有人失落,有的觉得收获满满有...
    陌忘宇阅读 8,534评论 28 53