zoukankan      html  css  js  c++  java
  • 从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上实现页面内容的更新,但是页面本身并没有刷新。

  • 相关阅读:
    Dockerfile中ENTRYPOINT 和 CMD的区别
    Dockerfile的书写规则和指令的使用方法
    docker+ bind mount 部署复杂flask应用
    VUE验证器哪家强? VeeValidate absolutely!
    DRF接入Oauth2.0认证[微博登录]报错21322重定向地址不匹配
    那些NPM文档中我看不懂地方
    “随机数”函数的 ES6 实现
    django-filter version 2.0 改动
    msgbox用法
    html01. <!DOCTYPE html>
  • 原文地址:https://www.cnblogs.com/itgezhu/p/11990910.html
Copyright © 2011-2022 走看看