Vue3页面首次进入加载页

2022-03-17 52 Vue3

介绍

Vue3 页面首次进入加载页 友好的实现加载等待

# 加载页的实现思路

  • Vue文件的加载顺序是 index.html -> 请求页面资源 -> App.vue ->页面的其他内容
  • 我们可以在index.html 写一个加载效果 然后当页面请求完毕资源后 在 App.vue 中做处理 隐藏在index.html的加载效果

image-20220317171636997

加载页样式浏览

zpbq9-0k4my

# 实现代码

  1. 先设置加载的css样式, 创建一个单独的css文件, 后面候通过<link />标签进行引用
<!-- 样式 -->
:root {
  --main-clr: rgb(0, 127, 255);
  --font-clr: rgba(255, 255, 255, 1);
}

#loading-mask {
  position: fixed;
  left: 0;
  top: 0;
  user-select: none;
  z-index: 2147483647;
  overflow: hidden;
  background: #2098d1;
  transition: 0.55s ease-in-out 0.16s;
  height: 100%;
  width: 100%;
  cursor: wait;
}

.container {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100%;
}

.txt {
  position: relative;
  top: 3rem;
  font-family: sans-serif;
  color: var(--font-clr);
}

.support {
  width: 2rem;
  height: 2rem;
  position: absolute;
  animation: rotation 3.8s linear infinite;
}

.support:nth-child(1) {
  animation-delay: 0.15s;
}

.support:nth-child(2) {
  animation-delay: 0.3s;
}

.support:nth-child(3) {
  animation-delay: 0.45s;
}

.support:nth-child(4) {
  animation-delay: 0.6s;
}

.support:nth-child(5) {
  animation-delay: 0.75s;
}

.support:nth-child(6) {
  animation-delay: 0.9s;
}

@keyframes rotation {
  0% {
    opacity: 0.8;
  }

  30% {
    transform: rotate(180deg);
    opacity: 1;
  }

  40% {
    transform: rotate(360deg);
    opacity: 1;
  }

  80% {
    transform: rotate(720deg);
    opacity: 0.8;
  }

  81% {
    opacity: 0;
  }

  100% {
    transform: rotate(0deg);
    opacity: 0;
  }
}

.dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--font-clr);
  position: relative;
  top: 37px;
  left: 7px;
}

.loadingapp {
  opacity: 0;
}

复制代码
  1. 按照浏览器执行的上下文方式, 强烈建议把css的文件放入 (opens new window) 进行引用, 这样可以提前引用到css样式表
    • <link /> 引用css样式表时候, 需要把rel (opens new window) 属性设置为stylesheet, css文本属性
    • <script> 引用js的逻辑代码, 注意:不允许标签省略, 开始标签和结束标签都不能省略, 必须<script> </script>

image-20230202171532521

<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width,initial-scale=1.0">
  <link rel="icon" href="<%= BASE_URL %>favicon.ico" />

  <!-- 导入加载css -->
  <link rel="stylesheet" href="./loading.css" referrerpolicy="origin" />

  <!-- 导入jq -->
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"
    integrity="sha512-894YE6QWD5I59HgZOGReFYm4dnWc1Qt5NtvYSaNcOP+u1T9qYdvdihz0PPSiiqn/+/3e7Jo4EaG7TubfWGUrMQ=="
    crossorigin="anonymous" referrerpolicy="no-referrer"></script>

  <!-- 导入gsap动画库 -->
  <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.11.4/gsap.min.js"
    integrity="sha512-f8mwTB+Bs8a5c46DEm7HQLcJuHMBaH/UFlcgyetMqqkvTcYg4g5VXsYR71b3qC82lZytjNYvBj2pf0VekA9/FQ=="
    crossorigin="anonymous" referrerpolicy="no-referrer"></script>

  <title>
    <%= htmlWebpackPlugin.options.title %>
  </title>
  <style>
  </style>
</head>
复制代码
  1. 通过jq的$(document).ready(), 来判断页面是否加载成功(类似于vue3的 onMounted), 再通gsap.to() (opens new window)设置一个隐藏的动画(opacity: 0), 最后通过onComplete隐藏动画结束后设置pointer-events: none穿透点击和z-index: -1降低层级, 或者直接给个display: none也可以
<script>
  $(document).ready(
    gsap.to("#loading-mask", {
      opacity: 0, ease: "elastic", delay: 0.5, ease: 'power2.out', onComplete: () => {
        $("#loading-mask").css("pointer-events", "none").css("z-index", "-1");
        // $("#loading-mask").css("display", "none")
      }
    })
  )
</script>
复制代码
  • 完整的html代码
<!DOCTYPE html>
<html lang="zh">

<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width,initial-scale=1.0">
  <link rel="icon" href="<%= BASE_URL %>favicon.ico" />

  <!-- 导入加载css -->
  <link rel="stylesheet" href="./loading.css" referrerpolicy="origin" />

  <!-- 导入jq -->
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"
    integrity="sha512-894YE6QWD5I59HgZOGReFYm4dnWc1Qt5NtvYSaNcOP+u1T9qYdvdihz0PPSiiqn/+/3e7Jo4EaG7TubfWGUrMQ=="
    crossorigin="anonymous" referrerpolicy="no-referrer"></script>

  <!-- 导入gsap动画库 -->
  <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.11.4/gsap.min.js"
    integrity="sha512-f8mwTB+Bs8a5c46DEm7HQLcJuHMBaH/UFlcgyetMqqkvTcYg4g5VXsYR71b3qC82lZytjNYvBj2pf0VekA9/FQ=="
    crossorigin="anonymous" referrerpolicy="no-referrer"></script>

  <title>
    <%= htmlWebpackPlugin.options.title %>
  </title>
  <style>
  </style>
</head>

<body>
  <noscript>
    <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled.
        Please enable it to continue.</strong>
  </noscript>
  <!-- 设置加载页 -->
  <div id="loading-mask">
    <div class="container">
      <div class="support">
        <div class="dot"></div>
      </div>
      <div class="support">
        <div class="dot"></div>
      </div>
      <div class="support">
        <div class="dot"></div>
      </div>
      <div class="support">
        <div class="dot"></div>
      </div>
      <div class="support">
        <div class="dot"></div>
      </div>
      <div class="support">
        <div class="dot"></div>
      </div>
      <p class="txt">Please wait</p>
    </div>
  </div>
  <!-- 内容页 -->
  <div id="app" />

  <!-- built files will be auto injected -->
</body>
<script>
  $(document).ready(
    gsap.to("#loading-mask", {
      opacity: 0, ease: "elastic", delay: 0.5, ease: 'power2.out', onComplete: () => {
        $("#loading-mask").css("pointer-events", "none").css("z-index", "-1");
        // $("#loading-mask").css("display", "none")
      }
    })
  )
</script>

</html>

复制代码

# 注意问题

  • 在苹果的safari浏览器中 会出现无法选中index.html中 除app以外的Dom 我们只能通过其他方式 实现首次加载页

# 备注

  • 我们注意到 可以用两种方式 实现页面加载完毕后 取消加载页 这两种生命周期有什么不同呢

Vue的 onMounted

原理:

  • 和jq的document.ready一样 表示文档结构已经加载完成(不包含图片 字体 等非文字媒体文件)DOM结构绘制完成之后就会执行,这样能确保就算有大量的媒体文件没加载出来,JS代码一样可以执行。可以配合nextTick

缺点:

  • onMounted的缺点很少 但是基于DOM结构绘制完成之后就会执行 并非所有网页资源已请求到 如果用户的网络很差 或者服务器延迟很高 那么不光字体和图片延迟显示 也会导致页面陷入空白 直到需要的js和css文件请求完毕后 才会显示 对于网络要求较高

原生方法 window.onload

原理:

  • 指示页面包含图片等文件在内的所有元素都加载完成。必须等到网页中所有内容全部加载完毕之后才被执行(包含图片 字体 等非文字媒体文件)。如果一个网页中有大量的图片的话,则就会出现这种情况:网页文档已经呈现出来,但由于网页数据还没有完全加载完毕,导致load事件不能够即时被触发(懒加载可以解决哦)

缺点:

  • 虽然懒加载可以解决图片加载问题 依旧需要请求文字等文件 等全部加载完毕后 才会显示完整的页面 这样虽然会让页面显示的很全面 但是无疑会增加用户加载时间

总结

  • onMounted的工作原理 类似于异步操作 当Dom结构绘制完毕后 就会执行 并不会管页面的js或者css等资源是否请求完毕 给用户的页面是需要加载的 (图片 字体等)
  • window.onload 的工作原理 类似于同步操作 全部资源都请求到位 才会执行 这样给用户的页面就是最完整的页面

# 参考文献

Last Updated: 2023/2/2 10:48:21
来发评论吧~
Powered By Valine
v1.4.14
未加载音频 - (ಗ ‸ ಗ )
00:00 / 00:00