详解从Vue-router到html5的pushState
最近在用vue的时候突然想到一个问题
首先,我们知道vue实现的单页应用中一般不会去刷新页面,因为刷新之后页面中的vuex数据就不见了。
其次,我们也知道一般情况下,url变更的时候,比如指定location.href、history.push、replace等,页面就会刷新。
那么问题来了,vue页面的页面跳转时怎么实现的?没刷新页面么?没刷新页面,又要改变url,加载新内容怎么做的?
去翻了一下vue-router的源码,找到这样一段
export class html5history extends history { ... push (location: rawlocation, oncomplete?: function, onabort?: function) { const { current: fromroute } = this this.transitionto(location, route => { pushstate(cleanpath(this.base + route.fullpath)) handlescroll(this.router, route, fromroute, false) oncomplete && oncomplete(route) }, onabort) } replace (location: rawlocation, oncomplete?: function, onabort?: function) { const { current: fromroute } = this this.transitionto(location, route => { replacestate(cleanpath(this.base + route.fullpath)) handlescroll(this.router, route, fromroute, false) oncomplete && oncomplete(route) }, onabort) } ... }
再看看方法内部
export function pushstate (url?: string, replace?: boolean) { savescrollposition() // try...catch the pushstate call to get around safari // dom exception 18 where it limits to 100 pushstate calls const history = window.history try { if (replace) { history.replacestate({ key: _key }, '', url) } else { _key = genkey() history.pushstate({ key: _key }, '', url) } } catch (e) { window.location[replace ? 'replace' : 'assign'](url) } }
答案就是html5在history中新增加的方法:pushstate和replacestate。这两个又是干啥的呢?(两个十分类似,以下以pushstate为例说明,区别和push与replace一致)
html5的pushstate()
首先看看这个是干什么的
pushstate方法就是向history中push一条记录,更改页面url,但是不刷新页面,不刷新页面,不刷新页面。不刷新页面,这点很关键,这和下面的操作很相似
window.location.href = window.location.href + '#a=b'
知道干嘛的了,再看看api怎么用的
history.pushstate(state, title, url);
state是一个对象,具体内容除了最大640kb之外没有别的限制,比如在vue中是生成了一个key存进去了。若无特殊需要传个null即可。这个state可以在history或者popstate的事件中看到
history中的
popstate中的
title这个参数目前没什么用处,可能是给以后预留的参数,暂时用null就好了
url很明显,就是替换后的url了。url可以接受绝对地址和相对地址,设置绝对地址的时候,要保证域名和当前域名一致,否则汇报如下错误
uncaught domexception: failed to execute 'pushstate' on 'history': a history state object with url 'https://www.baidu.com/' cannot be created in a document with origin 'https://mocard-aliyun1.chooseway.com:8443' and url 'https://mocard-aliyun1.chooseway.com:8443/views/h5/indexasdasd'.
at history.pushstate (https://aixuedaiimg.oss-cn-hangzhou.aliyuncs.com/static/m/js/alog/v1.0.0/alog.min.js:1:23259)
at <anonymous>:1:9
html5的popstate()
popstate与pushstate相对应,主要在页面url变更的时候触发,一般绑定在window对象下
window.addeventlistener('popstate', e => { console.log('popstate', ) })
前面pushstate中传入的state对象,可以在这边接收到,并根据需要去做一些处理。
说到这,vue-router是怎么实现页面“刷新”但不刷新的就知道了吧。
vue-router就是利用pushstate这个属性,在页面前进的时候动态改变history的内容,添加一条记录,接着location跟着改变。同时根据router前往的路由获取对应的js资源文件并挂载到目标dom上实现页面内容的更新,但是页面本身并没有刷新。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
上一篇: Ai怎么绘制很呆萌小男孩的头像?
下一篇: PHP调用C#开发的dll类库方法
推荐阅读