Maison  >  Article  >  interface Web  >  Analyse approfondie du problème de l'écran blanc de la commutation de routage dans Vue (avec code)

Analyse approfondie du problème de l'écran blanc de la commutation de routage dans Vue (avec code)

奋力向前
奋力向前avant
2021-08-24 10:54:424873parcourir

Dans l'article précédent "Une brève analyse du principe de liaison bidirectionnelle des données conformes dans Vue (explication détaillée du code)", nous avons découvert le principe de liaison bidirectionnelle des données conformes dans Vue. L'article suivant vous aidera à comprendre le problème de l'écran blanc lors du routage dans Vue. Jetons un coup d'œil.

Analyse approfondie du problème de l'écran blanc de la commutation de routage dans Vue (avec code)

Concernant l'écran blanc lors du changement de routage dans vue, en fait, je ne l'ai jamais rencontré pendant le processus de développement. vue路由切换的白屏,事实上在开发的过程中,我一直没有遇到过。

我有个哥们遇到这个问题,问我怎么解决的,我晕了,我没遇到这样的问题啊,我怎么解决啊啊啊啊。。

事实上是遇到过一回的。 

以下内容于 2019-07-25 修改。

服务器部署配置问题

这个问题造成的白屏体现在:

首页可以正常浏览,但是------通过$router.push('/home')跳转页面 正常,然后刷新就是白屏或 404

本不想在文章加入这个问题和解决方案,因为官网已经提供了正确的部署姿势,(Vue 的路由模式自行查看文档),主要是针对HTML5 History模式:

const router = new VueRouter({
  mode: 'history',
  routes: [...]
})

devbuild都没有问题,这个是肯定的,所以问题就出在服务器配置上,以nginx为例,正确的配置如下:

location / {
  ....
  try_files $uri $uri/ /index.html; #重点
}

Apache,原生 Node.jsIISCaddyFirebase 主机

请查看vur-router后端配置例子

地址:https://router.vuejs.org/zh/guide/essentials/history-mode.html#%E5%90%8E%E7%AB%AF%E9%85%8D%E7%BD%AE%E4%BE%8B%E5%AD%90

以上内容于 2019-07-25 修改。

以下内容于 2019-04-23 修改。

如果你是使用脚手架初始化环境,可以跳过这部分。如果自己配置webpack,可以接着看确定做了如下配置

devServer: {
  ...
  contentBase: false, //必须
  historyApiFallback: true, //必须
  ...
},
entry: {
    app: ['./src/main.js'],
    vendors: ['vue', 'vue-router'] //注意这里
},
plugins: [
  ....
  new HtmlWebpackPlugin({
    ...
    chunks: ['vendors', 'app'], //注意这里,这里的chunks 要包含入口的 entry
  })
]

以上内容于2019-04-23修改。

场景一:IE9(兼容性问题)

严格来说不是白屏的问题,应该说是兼容性问题,直接就是不支持,报错了,渲染无法执行造成的。解决方式就是

npm i babel-polyfill -D

然后在入口mian.js引入就完事了,就着么简单

import "babel-polyfill";

或者

//webpack
entry: {
      app: ['babel-polyfill','./src/main.js'],
      vendors: ['vue', 'vue-router']
},

以下内容于2019-04-23修改。

假如真的是js兼容性问题,那么真的只是引入babel-polyfill或者在webpack入口加入babel-polyfill问题就能解决吗,其实不一定的,这个要看项目的使用情况。babel-polyfill不是万能的。那么如何排查兼容性问题呢(假如真的是兼容性问题)。因为我们在手机上直接调试,有些错误不会那么容易显而易见。我是这么调试的。(仅供参考!)

<template>
  <div>
    <!-- 错误直接显示在这里. 不用 alert() ,console.log()  -->
    {{error}} ...
    <!-- other element -->
  </div>
</template>
<script>
  export default{
    data{
      return {
        error:&#39;&#39;
      }
    },
    moundted:{
      try{
        //一些请求数据的方法
      }catch(e){
        //这里抛出异常
        this.error = e
      }
    }
  }
</script>

这里要说的是有些兼容性问题是bable-polyfill搞不定的。比如URLSearchParams

let data = new URLSearchParams();
for (var key in params) {
  data.append(key, params[key]);
}

那么肯定会报URLSearchParams is not undefined,然后,错误只在一些低端的机型,一些偶然的场合出错.加大了错误的排查。

以下可以解决URLSearchParams is not undefined

//# console
npm i url-search-params-polyfill

//# mian.js
import &#39;url-search-params-polyfill&#39;;

以上内容于2019-04-23修改。

场景二 :如下图

有人说是在iphone 5s或者6s上会出现这种问题,肯定不是手机的bug。于是我重现了场景,真的和设备无关

Analyse approfondie du problème de lécran blanc de la commutation de routage dans Vue (avec code)

所以这个跟设备真的没有关系。知道问题所在,当然解决办法也有许多

方案一:暴力愚蠢型

//路由跳转前滚动条清零
document.body.scrollTop = document.documentElement.scrollTop = 0;
this.$router.push({ path: "/a/b/c" });

方案二:可行但不可选型

//给router 加一个监听,一旦改变,执行清零,然后再跳转
let routers = new Router({.....})
routers.beforeEach(function (to, from, next) {
    ......
    document.body.scrollTop = document.documentElement.scrollTop = 0
    next()
})

虽然可行,但是感觉着么干有点愚蠢。因为还有更好的写法,这个写法更佳优雅

方案三:最佳型

其实官方已经提供了当路由切换时,控制滚动位置的方式。scrollBehavior

使用方式如下:

const router = new VueRouter({
  routes: [...],
  scrollBehavior (to, from, savedPosition) {
    // return 期望滚动到哪个的位置 { x: number, y: number } |  { selector: string } |
  }
})

scrollBehavior方法接收tofrom路由对象。第三个参数savedPosition当且仅当popstate导航(通过浏览器的前进/后退按钮触发) 时才可用。 

所以假如要解决白屏的问题,可以着么干

const router = new VueRouter({
  routes: [...],
  scrollBehavior (to, from, savedPosition) {
    return savedPosition || { x: 0, y: 0 }
  }
})

也就是说,当用户点击返回、前进的时候,页面会滚动到之前位置,(微信朋友圈的文章就是这样的,读一半返回,再进来接着刚才的位置阅读)

如果是新的pagemounted进来的时候,就重置为 0

J'ai un copain qui a rencontré ce problème et m'a demandé comment le résoudre. Je me suis évanoui. Je n'ai jamais rencontré un tel problème. . 🎜🎜En fait, je l'ai rencontré une fois. 🎜🎜🎜Le contenu suivant a été modifié le 25/07/2019. 🎜🎜🎜Problème de configuration du déploiement du serveur🎜🎜L'écran blanc provoqué par ce problème se reflète dans : 🎜🎜La page d'accueil peut être parcourue normalement, mais ------via $router. push('/ home')La page saute normalement, puis s'actualise pour obtenir un écran blanc ou 404🎜🎜Je ne voulais pas inclure ce problème et cette solution dans l'article, car le site officiel a fourni le posture de déploiement correcte, (Vue Vérifiez vous-même la documentation du mode routage), principalement pour le mode HTML5 History : 🎜
<meta http-equiv="Expires" content="0" />
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Cache-control" content="no-cache" />
<meta http-equiv="Cache" content="no-cache" />
🎜 Il n'y a aucun problème avec dev et build, c'est sûr, donc le problème réside dans la configuration du serveur. En prenant nginx comme exemple, la configuration correcte est la suivante : 🎜rrreee. 🎜Apache, Node.js natif, IIS, Caddy, hôte Firebase🎜 🎜🎜Veuillez consulter l'exemple de configuration backend vur-router🎜🎜 Adresse : https://router.vuejs.org/zh/guide/essentials/history-mode.html#%E5%90% 8E%E7%AB%AF%E9%85%8D%E7%BD%AE%E4 %BE%8B%E5%AD%90🎜🎜🎜🎜Le contenu ci-dessus a été modifié le 25/07/2019. 🎜🎜🎜🎜Le contenu suivant a été modifié le 23/04/2019. 🎜🎜🎜Si vous utilisez un environnement d'initialisation d'échafaudage, vous pouvez ignorer cette partie. Si vous configurez webpack vous-même, vous pouvez vérifier et vous assurer que vous avez effectué la configuration suivante🎜rrreee🎜🎜Le contenu ci-dessus a été modifié le 23/04/2019. 🎜🎜

Scénario 1 : IE9 (problème de compatibilité)

🎜À proprement parler, il ne s'agit pas d'un problème d'écran blanc. Il faut dire qu'il s'agit d'un problème de compatibilité. Il n'est tout simplement pas pris en charge, une erreur est signalée. et le rendu ne peut pas être exécuté. La solution est de 🎜rrreee🎜 puis de l'importer dans main.js à l'entrée. C'est aussi simple que 🎜rrreee🎜 ou
🎜rrreee🎜🎜Le contenu suivant a été modifié le 23/04/2019. 🎜🎜🎜S'il s'agit vraiment d'un problème de compatibilité js, il suffit alors d'introduire babel-polyfill ou d'ajouter babel au <code>webpack code> Entry -polyfill peut-il résoudre le problème ? En fait, pas nécessairement Cela dépend de l'utilisation du projet. babel-polyfill n'est pas une panacée. Alors, comment résoudre les problèmes de compatibilité (s'il s'agit vraiment d'un problème de compatibilité). Comme nous déboguons directement sur le téléphone, certaines erreurs ne seront pas aussi évidentes. C'est ainsi que je l'ai débogué. (Pour référence seulement !) 🎜rrreee🎜Ce que je veux dire ici, c'est qu'il y a certains problèmes de compatibilité que bable-polyfill ne peut pas résoudre. Par exemple, URLSearchParams🎜rrreee🎜 signalera certainement URLSearchParams n'est pas indéfini. Ensuite, l'erreur ne se produira que sur certains modèles bas de gamme et à certaines occasions occasionnelles. sera augmentée d’enquête. 🎜🎜Ce qui suit peut résoudre le problème URLSearchParams n'est pas indéfini🎜rrreee🎜🎜Le contenu ci-dessus a été modifié le 23/04/2019. 🎜🎜🎜Scénario 2 : Comme indiqué ci-dessous🎜🎜Certaines personnes disent que ce problème se produit sur l'iPhone 5s ou 6s. Ce n'est certainement pas un bug du téléphone. J'ai donc reproduit la scène, ça n'a vraiment rien à voir avec l'appareil🎜🎜WeChat screenshot_20210824104023.jpg🎜🎜Donc, cela n'a vraiment rien à voir avec l'appareil. Connaissant le problème, il existe bien sûr de nombreuses solutions 🎜🎜Option 1 : Type violent et stupide🎜rrreee🎜Option 2 : Faisable mais pas facultative🎜rrreee🎜Bien que ce soit faisable , on a l'impression que ce que tu fais est un peu stupide. Parce qu'il existe une meilleure façon d'écrire, cette façon d'écrire est plus élégante🎜🎜Option 3 : Meilleur type🎜🎜En fait, le responsable a fourni un moyen de contrôler la position de défilement lorsque l'itinéraire est commuté. scrollBehavior🎜🎜Utilisation comme suit : 🎜rrreee🎜La méthode scrollBehavior reçoit les objets de routage vers et de. Le troisième paramètre savedPosition est disponible si et seulement si la navigation popstate (déclenchée par les boutons avant/arrière du navigateur). 🎜🎜Donc si vous voulez résoudre le problème de l'écran blanc, que pouvez-vous faire🎜rrreee🎜C'est-à-dire que lorsque l'utilisateur clique en arrière ou en avant, la page défilera jusqu'à la position précédente (c'est l'article de WeChat Moments, demi-lecture Revenez en arrière, puis entrez et continuez la lecture à partir de la position précédente) 🎜🎜Si une nouvelle page est montée à l'arrivée, elle sera réinitialisée à 0. 🎜

完美的解决了这个问题。

但是这也是个问题,框架为什么不默认呢,假如自定义的时候可以overwirte

场景三: 缓存的原因(2019.4.15)

我们根据版本号(或者hash)去控制缓存问题,当我们发布新版本,会发现html里面引用的版本号却是旧的版本号 ,这种情况是入口index.html文件被缓存了,很多时候我们设置禁止html文件被缓存,但依然会出现被缓存的情况。比如在头部加

<meta http-equiv="Expires" content="0" />
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Cache-control" content="no-cache" />
<meta http-equiv="Cache" content="no-cache" />

仍然解决不了问题,关于web的缓存策略,推荐这篇文章:Http缓存机制

一旦index.html被缓存了,之后我们使用了全量更新,也就是每次发版本之前会干掉之前的jscss文件,那么被缓存的index.html会无法加载之前旧的js,css还有一些其他的静态资源文件,而新的jscss则不会被加载,那么白屏就诞生了。

这个时候我们就要配合服务端来解决index.html的缓存问题

解决缓存的问题请转到这里:Vue index.html入口缓存问题

[完]

推荐学习:vue.js教程

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer