13.vue 单页面如何实现在静态图片加载完成后进行的一个渲染操作

书诚小驿2024/12/04前端知识库Vue3

一、问题描述

今天在做一个 h5 页面嵌入到 app 页面的组件时,遇到一个需求:在图片加载完成后,进行一个渲染操作。点击跳转打开 app 页面。当网速较慢时,图片加载时间较长,导致渲染操作在图片加载完成前就执行了,导致渲染操作失败。

<template>
  <div class="wrapper">
    <img class="h5Img" src="@/assets/images/activities/H5.png" />
    <login-dialog ref="loginDialogEL" :channel="'refund'" />
  </div>
</template>

<script setup>
import { ref, onMounted } from "vue";
import loginDialog from "../components/login-dialog.vue";
const loginDialogEL = ref(null);
const route = useRoute();
const router = useRouter();
onMounted(() => {
  if (route.query.isLogin === "true") {
    loginDialogEL.value.isShowLogin = true;
    return;
  }
});
</script>

<style lang="scss" scoped>
.wrapper {
  width: 100vw;
}
.h5Img {
  width: 100vw;
  height: 100%;
}
</style>

二、解决思路

  1. 问题原因:图片加载完成前,渲染操作已经执行了,导致渲染操作失败。
  2. 解决方案:在图片加载完成后,进行一个渲染操作。

三、解决方案

1、 在静态图片资源加载完成后进行路由操作,可以通过监听图片的 load 事件来实现。在模板中添加图片元素,并绑定 load 事件处理器

<template>
  <div class="wrapper">
    <img
      class="h5Img"
      src="@/assets/images/activities/H5.png"
      @load="loadImg"
    />
    <login-dialog ref="loginDialogEL" :channel="'refund'" />
  </div>
</template>

<script setup>
import { ref } from "vue";
import loginDialog from "../components/login-dialog.vue";
const loginDialogEL = ref(null);
const route = useRoute();
const router = useRouter();
const loadImg = () => {
  if (route.query.isLogin === "true") {
    loginDialogEL.value.isShowLogin = true;
    return;
  }
};
</script>

<style lang="scss" scoped>
.wrapper {
  width: 100vw;
}
.h5Img {
  width: 100vw;
  height: 100%;
}
</style>

2、 通过 js 监听图片加载完成事件,也适用于监听一个 image 是一个数组时

<template>
  <div class="wrapper">
    <img class="h5Img" ref="imageElement" @load="loadImg" />
    <login-dialog ref="loginDialogEL" :channel="'refund'" />
  </div>
</template>

<script setup>
import { ref, onMounted } from "vue";
import imagePath from "@/assets/images/activities/H5.png";
import loginDialog from "../components/login-dialog.vue";
const loginDialogEL = ref(null);
const route = useRoute();
const router = useRouter();
// 创建一个ref来存储图片元素
const imageElement = ref(null);
onMounted(() => {
  // 创建一个Image对象
  const img = new Image();
  // 监听load事件
  img.onload = function () {
    handleImageLoad();
  };
  img.onerror = function () {
    console.error("图片加载失败");
  };
  img.src = imagePath;
  imageElement.value.src = imagePath;
});

// 定义handleImageLoad函数
function handleImageLoad() {
  // 这里可以执行路由跳转或其他逻辑
  if (route.query.isLogin === "true") {
    // 这里弹出登录弹窗
    loginDialogEL.value.isShowLogin = true;
    return;
  }
}
</script>

<style lang="scss" scoped>
.wrapper {
  width: 100vw;
}
.h5Img {
  width: 100vw;
  height: 100%;
}
</style>
最后更新时间' 2025/1/3 14:16:58