• Vue--Router--各个版本的事件监听


    原文网址:Vue--Router--各个版本的事件监听_IT利刃出鞘的博客-CSDN博客

    简介

            本文介绍Vue-router各个版本的事件监听的区别。

    问题引出

            在学习vueRouter源码时发现,路由变化的监听是通过popstate或者hashchange来监听路由变化的。但在使用中发现,不同版本处理的效果不一致,比如:在3.1.6版本通过push等方法更新路由的时候,不会触发hash中路由监听事件;但是在3.0.3版本中,是会触发的路由监听事件的。

            那么,导致这些的原因到底是什么呢?首先我们来分析下两种事件监听的特点

    popstate事件

            调用history.pushState()或history.replaceState()不会触发popstate事件。只有在做出浏览器动作时,才会触发该事件,如用户点击浏览器的回退按钮(或者在Javascript代码中调用history.back()。

    详见:JS--history--使用/教程/实例_IT利刃出鞘的博客-CSDN博客_js中history

    hashchange事件

    只要锚点也就是hash值有更新,就会触发hashchange监听事件。

    详见:JS--hashchange事件--使用/教程_IT利刃出鞘的博客-CSDN博客

    了解了两种路由监听事件的特点后,再去分析源码就简易多了。

    源码分析

    概述

    更新路由的方法:浏览器判断是否支持pushstate方法。

    1. 若支持:调用pushstate、replacestate等方法更新路由;
    2. 若不支持:使用window.location.hash去更新。

    监听路由变化的方法:浏览器判断是否支持pushstate方法。

    1. 若支持:监听popstate事件;
    2. 若不支持:监听hashchange事件。

    vue-router3.1.6

    1. var supportsPushState =
    2. inBrowser &&
    3. (function () {
    4. var ua = window.navigator.userAgent;
    5. if (
    6. (ua.indexOf('Android 2.') !== -1 || ua.indexOf('Android 4.0') !== -1) &&
    7. ua.indexOf('Mobile Safari') !== -1 &&
    8. ua.indexOf('Chrome') === -1 &&
    9. ua.indexOf('Windows Phone') === -1
    10. ) {
    11. return false
    12. }
    13. // 谷歌浏览器return true
    14. return window.history && 'pushState' in window.history
    15. })();
    16. // hash监听方法
    17. // 若支持pushstate,则监听popstate,否则监听hashchange
    18. window.addEventListener(
    19. supportsPushState ? 'popstate' : 'hashchange',
    20. function () {
    21. var current = this$1.current;
    22. if (!ensureSlash()) {
    23. return
    24. }
    25. this$1.transitionTo(getHash(), function (route) {
    26. if (supportsScroll) {
    27. handleScroll(this$1.router, route, current, true);
    28. }
    29. if (!supportsPushState) {
    30. replaceHash(route.fullPath);
    31. }
    32. });
    33. }
    34. );
    35. // 更新路由方法
    36. // 若支持pushstate则调用history.pushstate,否则调用window.location更新路由
    37. function pushHash(path) {
    38. if (supportsPushState) {
    39. pushState(getUrl(path));
    40. } else {
    41. window.location.hash = path;
    42. }
    43. }

    vue-router3.0.3

    其他部分一样,只看supportsPushState方法:

    1. var supportsPushState = inBrowser && (function () {
    2. var ua = window.navigator.userAgent;
    3. // 与316版本相比多出来的判断。谷歌浏览器访问return false,即不支持pushstate方法
    4. if (ua.indexOf('Chrome') !== -1) {
    5. return false
    6. }
    7. if (
    8. (ua.indexOf('Android 2.') !== -1 || ua.indexOf('Android 4.0') !== -1) &&
    9. ua.indexOf('Mobile Safari') !== -1 &&
    10. ua.indexOf('Chrome') === -1 &&
    11. ua.indexOf('Windows Phone') === -1
    12. ) {
    13. return false
    14. }
    15. return window.history && 'pushState' in window.history
    16. })();

    原因总结

    vue-router3.1.6

    • 谷歌浏览器支持pushstate(supportsPushState值为true)
      • pushHash最终调用的是pushState
      • 路由监听的事件是popstate
    • popstate不会触发popstate事件监听

            路由变化不会触发事件监听,所以调用push方法只触发一次transitionTo方法,只更新一次视图。

    vue-router3.0.3

    • 谷歌浏览器不支持pushstate(supportsPushState值为false)
      • pushHash最终调用的是window.location.hash
      • 路由监听的事件是hashchange
    • pushHash最后调用的window.location.hash方法触发了hashchange监听的事件

            此时路由变化就会触发事件监听,所以我们调用push方法会触发两次transitionTo方法,但是由于我们在confirmTransition中有相同路径就不继续往下走的拦截,所以,最后只会更新一次视图。

    其他网址

    https://www.jianshu.com/p/073c3826541b

  • 相关阅读:
    WPF DataGrid开箱即用支持全部勾选的DataGridCheckBoxColumn
    HMS Core Discovery第17期直播预告|音随我动,秒变音色造型师
    springboot+vue的校友会捐赠信息java社交系统
    腾讯视频跟爱奇艺视频共享设备ip会不会出现错误
    自动化测试,你一定要知道的知识
    软件测试的学习笔记(3)
    11. 关于linux下的挂载
    阿里云RDS CPU100%排查
    Flink学习笔记(六)Flink的时间和窗口
    极智AI | 讲解 TensorRT 显式batch 和 隐式batch
  • 原文地址:https://blog.csdn.net/feiying0canglang/article/details/126131061