山东大学软件学院项目实训-基于大模型的模拟面试系统-网页图片显示问题

具体专栏图片显示问题

根据之前对于图片显示的修改,图片能够正常显示,但是只能够显示一瞬间,不到一秒钟之后图片就又变成上图所示的情况。

下面对于该问题进行修改:

我尝试了许多方案,一开始我以为是图中控制台下面的那个GET请求报错的问题,然后通过这一个线索进行排错,但是尝试了很久之后还是没有解决。

之后我就想看看图片显示用到的imgUrlportfolio.idPortfolio在图片无法显示时它们的值是什么,于是我直接将imgUrlportfolio.idPortfolio输出到页面上,发现在图片无法显示时它们的值还是正常的。于是,我把源码和问题描述给了AI,一开始它并没有给出正确答案,而是给了一下几个原因分析:

  1. fetch 钩子异步加载数据后覆盖了 imgUrl,你在 mounted 里调用了 fetchImageAsBase64(),它会设置 imgUrl。但 fetch() 钩子(或 asyncData)可能稍后加载 portfolio 数据,导致 imgUrl 被重置(比如portfolio.headImgUrl 为空)。
  2. portfolio 数据变化触发了重新渲染,如果 portfolio 是 computed 属性(来自 Vuex),当 fetchDetail 完成后,portfolio更新,可能间接导致 imgUrl 被清空。
  3. el-image 组件内部处理 Base64 的问题,el-image 可能会对 src 进行额外处理,如果 imgUrl 变化,可能会导致图片闪烁。

之后它又给出了一个可行的方案:

el-image 默认支持 Base64,但如果你的 Element UI 版本较旧,可能存在兼容性问题。

于是我尝试把el-image改为image,但这一改改"错"了,我把

vue 复制代码
<el-image>
	// 正常图片
</el-image>
<el-image>
	// 无图片
</el-image>

改成了

vue 复制代码
<el-image>
	// 正常图片
</el-image>
<image>
	// 无图片
</image>

但图片能够正常显示了。

后来发现可能是因为组件中的v-if条件写的不规范导致的。

修改前的代码:

vue 复制代码
<el-col :span="8" v-if="imgUrl">
  <el-image
    style="width: 200px;height: 200px;border-radius: 16px;background: #f5f7fa;border: #f5f7fa solid 1px;"
    :src="imgUrl" :preview-src-list="[imgUrl]" lazy></el-image>
</el-col>
<el-col :span="8" v-else>
  <el-image
    style="width: 200px;height: 200px;border-radius: 16px;background: #f5f7fa;border: #f5f7fa solid 1px;">
    <div slot="error"
         style="display: flex;justify-content: center;align-items: center;width: 100%;height: 100%;background: #f5f7fa;color: #909399;">
      无图片
    </div>
  </el-image>
</el-col>

修改后能正常显示的代码:

vue 复制代码
<el-col :span="8" v-if="imgUrl != null">
  <el-image
    style="width: 200px;height: 200px;border-radius: 16px;background: #f5f7fa;border: #f5f7fa solid 1px;"
    :src="imgUrl" :preview-src-list="[imgUrl]" lazy></el-image>
</el-col>
<el-col :span="8" v-else>
  <el-image
    style="width: 200px;height: 200px;border-radius: 16px;background: #f5f7fa;border: #f5f7fa solid 1px;">
    <div slot="error"
         style="display: flex;justify-content: center;align-items: center;width: 100%;height: 100%;background: #f5f7fa;color: #909399;">
      无图片
    </div>
  </el-image>
</el-col>

专栏管理页面图片显示问题

这部分可以复用上述的部分代码,但也有些不同,因为这次不是单一图片的显示,而是需要一个列表来存储id和图片,然后在显示的时候通过id展示相应的图片。

vue 复制代码
<el-col :xs="24" :sm="12" :md="12" v-for="portfolio in portfolios.list" :key="portfolio.idPortfolio">
  <el-col style="margin-bottom: 20px;">
    <el-card>
      <el-col :span="12">
        <el-image :src="getImageUrl(portfolio.idPortfolio)"
                  style="width:96px;height: 96px;border-radius: 10px;background: #f5f7fa;border: #f5f7fa solid 1px;"
                  fit="cover"
                  :preview-src-list="previewImageList">
          <div slot="error"
               style="display: flex;justify-content: center;align-items: center;width: 100%;height: 100%;background: #f5f7fa;color: #909399;">
            无图片
          </div>
        </el-image>
      </el-col>
      <el-col :span="12" style="padding-top: 30px;text-align: right;">
        <el-button @click="onRouter('portfolio', portfolio.idPortfolio)" round>阅读</el-button>
      </el-col>
      <el-col style="padding-top: 20px;font-size: 16px;line-height: 22px;font-weight: 500;margin-bottom: 4px;">
        <span class="portTitle" v-html="portfolio.portfolioTitle"></span>
      </el-col>
      <el-col style="padding-bottom: 20px;font-size: 14px;">
        <span>{{ portfolio.articleNumber || 0 }} 篇文章</span>
      </el-col>
    </el-card>
  </el-col>
</el-col>

上述对于组件的修改主要是添加了一个函数(如下),来计算当前应该显示的图片的URL

javascript 复制代码
// 根据 portfolio.idPortfolio 获取对应的图片URL
getImageUrl(portfolioId) {
  const found = this.imgList.find(item => item.id === portfolioId);
  return found ? found.url : '';
}

在一开始,我们就需要根据portfolios.list获取所有的图片列表存起来,供之后使用。

javascript 复制代码
mounted() {
  console.log(this.portfolios.list);
  if (this.portfolios.list && Array.isArray(this.portfolios.list)) {
    for (const portfolio of this.portfolios.list) {
      this.fetchImageAsBase64(portfolio.idPortfolio);
    }
  }
  console.log(this.imgList.length); 
},
computed: {
  // 提取imgList中的所有URL用于预览
  previewImageList() {
    return this.imgList.map(item => item.url);
  },
}

下面的函数就是复用之前的函数稍加修改了一下,注释掉的就是之前的函数被删除的部分。

javascript 复制代码
async fetchImageAsBase64(id) {
  try {
    const response = await this.$axios.$get(
      `/api/portfolio/image/${id}/base64`,
      { responseType: 'text' }
    );
    this.imgList.push({
      id: id,
      url: response
    });
    console.log(this.imgList)
    // this.imgUrl = response;
  } catch (error) {
    console.error('获取Base64图片失败:', error);
  } finally {
    this._fetchingImage = false;
  }
},

成功修复!!!

相关推荐
软件技术NINI13 分钟前
html css js网页制作成品——HTML+CSS+js美甲店网页设计(5页)附源码
javascript·css·html
天天扭码25 分钟前
从数组到对象:JavaScript 遍历语法全解析(ES5 到 ES6 + 超详细指南)
前端·javascript·面试
拉不动的猪26 分钟前
前端开发中常见的数据结构优化问题
前端·javascript·面试
三原1 小时前
2025 乾坤(qiankun)和 Vue3 最佳实践(提供模版)
vue.js·架构·前端框架
天天扭码1 小时前
ES6 Symbol 超详细教程:为什么它是避免对象属性冲突的终极方案?
前端·javascript·面试
小矮马1 小时前
React-组件和props
前端·javascript·react.js
DC...2 小时前
vue滑块组件设计与实现
前端·javascript·vue.js
H5开发新纪元2 小时前
Vite 项目打包分析完整指南:从配置到优化
前端·vue.js
吃面必吃蒜3 小时前
从 Vue 到 React:React 合成事件
javascript·vue.js·react.js
前端练习生3 小时前
vue2如何二次封装表单控件如input, select等
前端·javascript·vue.js