为什么我的page页面会重复渲染两次书本的封面图?

<template>
  <div class="page_views" ref="pageViews"  tabindex="0" @keydown="handleKeyDown">
    <Menu :val="user.pageIdx" @meuId="chengmenu"></Menu>
    <div class="page_contents">
      <template v-if="titles">
        <div class="page_content" v-show="user.pageIdx !==1">
          <p class="page_title">{{ titles.title }}</p>
          <div class="page_title_right">
            <input type="number"

                   v-model="inputPage"
                   @blur="updatePage"
                   @keydown.enter="updatePage"
                   class="page_input"/>
            <p>/{{ total.total_page }} 页</p>
          </div>
        </div>
        <div class="book-cover"
             v-if="bookInfo.cover_pic != null && user.pageIdx === 1"
             :style="{backgroundImage: 'url(' + bookInfo.cover_pic + ')'}">
        </div>
        <div class="raw_text" v-html="titles.content" v-if="user.pageIdx !==1" @click="openImage"></div>
      </template>
      <img :src="KeyDownLeft" alt="keyDownLeft-Icon" class="keyDownLeft Icon" @click="prevPage">
      <img :src="KeyDownRight" alt="KeyDownRight-Icon" class="KeyDownRight Icon" @click="nextPage">
      <img :src="Quit" alt="KeyDownQuit-Icon" class="KeyDownQuit Icon" @click="Exithand">
    </div>
    <Sunny/>
    <div class="demo-image">
      <el-image-viewer
          v-if="imageViewer"
          :url-list="previewList"
          :hide-on-click-modal="true"
          @close="imageClose"
      />
    </div>
  </div>
</template>
<script setup lang="ts">
import Menu from "../../components/Menu/index.vue";
import {getinfo, getpage} from '../../api';
import {onMounted, ref} from "vue";
import {useReadStore} from "../../stores/readstore.ts"
import router from "../../router";
import KeyDownLeft from '../../assets/svg/Left.svg'
import KeyDownRight from '../../assets/svg/Right.svg'
import Quit from '../../assets/svg/Quit.svg'
import Sunny from '../../components/Sunny/index.vue'
import {Page} from "../../types/page.ts";
//输入框获取焦点
const pageViews = ref<HTMLElement | null>(null);
const readstore = useReadStore();
const titles: any = ref('');
const bookInfo: any = ref('');
const inputPage: any = ref(1);
//图片预览数组
const previewList = ref(new Array<string>());
// 图片预览
const imageViewer = ref(false);
onMounted(() => {
  const page=readstore.getBook('page');
  localPage(page,user,pageViews);
  //等待恢复到刷新前查看的书籍页数在发起请求
  LocalHttp();
})
const total: any = ref('');
let pageCount = 0;
let user: any = {
  bookId: readstore.getBook('book').bookId,
  pageIdx: 1,
  size: 2
};

/**
 * 利用本地存储覆盖user值
 * 完成页面刷新不会重新回到第一页
 * @param val 本地存储值 key page
 * @param viwes ref 值
 * @param use 当前值
 */
const localPage = (val: any,use:any, viwes: any) => {
  if (val && val.pageIdx) {
    use.pageIdx = val.pageIdx;
  }
  if (viwes) {
    viwes.value.focus;
  }
}

const LocalHttp = async () => {

  await http(user);
}

const http = (val: any) => {

  getinfo(val).then(res => {
    total.value = res.data.results[0];
    bookInfo.value = res.data.results[0];
    console.log(bookInfo.value.cover_pic);
  });

  getpage(<Page>val).then(res => {
    titles.value = res.data.results[0];
    inputPage.value = user.pageIdx;
  })

}
/**
 * Menu子组件传值点击目录页数
 * 完成目录跳转页面
 * @param val
 */
const chengmenu = async (val: any) => {
  user.pageIdx = val;
  await http(user);
  readstore.setBook('page', user);
};
/**
 * 上一页下一页
 *键盘按键事件处理
 */
//节流翻页事件;
const handleKeyDown = async (event: KeyboardEvent) => {
  if (imageViewer.value) {
    return
  }
  let keys: Map<string, ((event: KeyboardEvent) => Promise<void>) | (() => void)> = new Map([
    ['ArrowLeft', prevPage],
    ['d', nextPage],
    ['a', prevPage],
    ['w', () => {
      Quitopen();
    }],
    ['ArrowRight', nextPage],
    ['Escape', Exithand],
  ]);
  const action = keys.get(event.key);
  if (action) {
    await action(event);
  }

};
/**
 * 上一页
 */
const prevPage = async () => {
  user.pageIdx = user.pageIdx > 1 ? user.pageIdx - 1 : user.pageIdx;
  readstore.setBook('page', user);
  await http(user);
};

/**
 * 下一页
 */
const nextPage = async () => {
  user.size = pageCount == 1 ? 2 : 5
  user.pageIdx++;
  readstore.setBook('page', user);
  await http(user);
};

const Exithand = async () => {
  await router.push('/');
}

const updatePage = async () => {
  const page = Number(inputPage.value);
  if (page >= 1 && page <= total.value.total_page) {
    user.pageIdx = page;
    readstore.setBook('page', user);
    await http(user);
  } else {
    inputPage.value = user.pageIdx; // 如果输入的页码无效,重置为当前页码
  }
};

/**
 * 关闭图片预览
 */
const imageClose = () => {
  imageViewer.value = false;
}

/**
 * 点击图片后开启预览
 * @param event
 */
const openImage = (event: any) => {
  const target = event.target;
  if (target.src != undefined) {
    previewList.value = [target.src];
    imageViewer.value = true;
  }
}
const Quitopen = () => {
  if (imageViewer.value) {
    imageViewer.value = false;
    return;
  }

  let imageList = document.querySelectorAll(".raw_text img");
  let srcList = new Array<string>();
  for (let img of imageList) {
    let src = img.attributes.getNamedItem("src");
    if (src instanceof Attr && src.value != null) {
      srcList.push(src.value);
    }
  }

  if (srcList.length != 0) {
    previewList.value = srcList;
    imageViewer.value = true;
  }
}

</script>

为什么我的这个page页面会重复渲染两次书本的封面图片

我打印拼接的路径为undefined请求成功但是状态码为304能拿到图片我的图片路径是拿到后端返回的片段路径进行拼接的

阅读 777
avatarAI BotBETA

你的页面出现重复渲染书本封面图片的问题,以及图片路径拼接后请求状态码为304,可能是由以下几个原因导致的:

  1. Vue组件的渲染逻辑

    • 在你的模板中,<div class="book-cover"> 使用了 v-if="bookInfo.cover_pic != null && user.pageIdx === 1" 来判断是否显示封面。如果 bookInfo.cover_pic 初始为 nullundefined,但在数据更新后变为有效路径,并且 user.pageIdx 保持为1,那么这个 div 会被重新渲染。
    • 如果你的数据(如 bookInfo.cover_pic)在组件的多个地方被更新或异步获取,可能会导致在数据最终确定前,模板已经根据旧数据进行了渲染,随后又根据新数据进行了重新渲染。
  2. 数据更新时机

    • 你的 onMounted 钩子中调用了 localPageLocalHttp 函数,这些函数可能异步更新了 bookInfo.cover_pic。如果在这个过程中,组件的其它部分(如计算属性或侦听器)也依赖于这些数据,那么可能会在数据最终确定前导致多次渲染。
  3. 浏览器缓存

    • 请求状态码304表示请求的资源自上次请求后没有修改,因此服务器没有返回资源本身,而是告知浏览器可以使用其缓存的版本。这通常不是导致重复渲染的直接原因,但可能会影响你看到的内容。
  4. 解决策略

    • 确保你的数据(如 bookInfo.cover_pic)在组件渲染前已经正确获取并设置。你可以考虑在数据获取完成后再进行渲染,例如使用 v-if 来确保只有在数据有效时才渲染相关部分。
    • 检查你的异步数据获取逻辑,确保不会在数据最终确定前进行不必要的渲染。
    • 如果可能,考虑使用Vue的响应式系统来更好地控制渲染时机,例如使用计算属性或侦听器来响应数据的变化。
    • 检查浏览器的开发者工具中的网络请求,确认 bookInfo.cover_pic 的请求是否确实只发生了一次,并且是在正确的时机。
  5. 代码改进建议

    • 确保 bookInfo.cover_pic 在渲染前已经是一个有效的URL,或者在模板中使用条件渲染来避免无效渲染。
    • 可以在 getinfogetpage 的回调中添加更详细的日志,以跟踪数据获取和渲染的时机。
    • 考虑使用Vue的 watchcomputed 属性来监听 bookInfo.cover_pic 的变化,并在变化时执行必要的逻辑。
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏