请稍等 ...
×

采纳答案成功!

向帮助你的同学说点啥吧!感谢那些助人为乐的人

3.2-3.5 不太理解这几节中通过图片名动态加载图片路径的做法

本身我开发的经验并不多,刚接触 Vite,且对项目发布、部署等流程也不太了解,之后的章节也还没看。看了这几节后,提出下面的问题可能会有点过早。但现在实在想不通这种做法,于是就提出来了。


视频中用 Vite 来处理图片资源,那 npm run build 打包生成的 dist 目录中的 js 文件代码中含有图片名和对应的图片路径,而且我们还让用户前端在第一次打开网页时,本地缓存这些图片名和图片路径,之后再次打开网页时,从本地缓存中读取这些图片名和图片路径就可以了。
图片描述
这样打包上线,我的疑惑是这样不会有以下问题吗:

  1. 如果有上千万本图书,这样打包生成的 js 代码会不会过长?导致加载 js 代码时间长?
  2. 如果要新增图书图片,是不是每次都要重新打包一次?
  3. 如果图片路径发生了变化,用户前端本地缓存中保存的图书名以及对应的图书路径如何也变更?
  4. 此时 npm run preview 显示不了图片,比如我们想这样加载图片 <img :src="getImg('白夜行.png')" />,但打包生成的图片名已变成 白夜行.56b0275d.png,所以我们加载不了图片。而且,之后我们可能写这样的代码<img :src="getImg(bookitem.bookpicname)" />,我不知 Vite 每次打包生成的图片名是否都一样?如果不一样,存储在数据表中的图片名应该也应该变更?

正在回答 回答被采纳积分+3

2回答

keviny79 2022-08-19 21:36:38
  1. 显示图片没问题:npm run preview  使用过时的import.meta.globEager也能显示图片 ,今天我刚更新到高版本的 vite , import.meta.glob方法也测过了,也没问题:高版本的vite 编写的代码如下:

import storage from 'good-storage'

export class LmgLoader {

  static imgList: Record<string, any> = {}


  static async getimgList() {

    this.imgList = storage.get('imgList') || {}

    if (!LmgLoader.imgList || !LmgLoader.isNotEmptyimgList()) {

      this.imgList = LmgLoader.getImgAll()

      storage.set('imgList', LmgLoader.imgList)

    }

  }


  static isNotEmptyimgList() {

    return Object.getOwnPropertyNames(LmgLoader.imgList).length

  }

  static getImg(name: string): string {

    //console.log('name:', name)

    // LmgLoader.imgList = LmgLoader.isNotEmptyimgList() ? LmgLoader.imgList : storage.get('imgList')

    return LmgLoader.imgList[name] //

  }


  static getImgAll(): any {

    const imgList: any = {}

    const viewImgModules: Record<string, any> = import.meta.glob(`../assets/img/**/**/*.png`, { eager: true })

    // import.meta.globEager(`../assets/img/**/**/*.png`)

    for (const path in viewImgModules) {

      if (viewImgModules[path].default) {

        const pathName = path.substring(path.lastIndexOf('/') + 1)

        imgList[pathName] = viewImgModules[path].default

      }

    }

    storage.set('imgList', this.imgList)

    return imgList

  }

}


export default LmgLoader.getImg



0 回复 有任何疑惑可以回复我~
keviny79 2022-08-19 00:16:13

同学:这样写动态加载图片能给项目的维护性和扩展性带来相当大的好处,你就放心用吧。

如果不动态加载,那么图片路径管理只有两种做法,做法1:把图片路径保存到数据表中,取出来即可,这会让数据表对图片的管理变得很繁琐,而且从后端数据表取出图片名的速度会下降,因为带着路径,这在高并发场景下无疑是一个损耗! 做法2:就是在项目中手动管理路径,因为一个大项目图片非常多,那么多路径都要管理,都要维护,这浪费了很多时间,大大增加了维护的负担!而且一旦图片路径变了,就需要修改代码,扩展性很不好!

做法2还有一个问题就是,你动态从数据表获取到一个图片,然后和你页面上的图片路路径连接,当打包后,vite 2.x 版本的npm run preview 获取不到图片,3.x 也测过了,没问题,代码已经贴在下方!

解答你的问题:

首先你说的正确,应该保存到缓存中,不用每次刷新都加载图片,视频中补讲了缓存

  1. 这个不会,因为加载的数据只是一些本地的一些key-value的数据,而不是真实图片,千万 key-value  加载也会很快,  而且用到了缓存,除了刚启动第一次加载,后面就不用再加载了, 加之 vite使用了 esbuild 预构建,基于 go 语言,其速度比之前的 webpack 快了上百倍,所以上万个key-value加载,也算不了什么

  2. 增加了图片,不管你用不用老师讲到的加载图片的方法, 都需要重新打包,打包的原因是你增加了新的资源。

  3. 实际开发时,图片路径一般保存好了,一般很少会变的,即使变了,删除下缓存,重新加载就ok了。对比传统的路径写到代码中,一旦路径变了,那远比咱们动态加载图片麻烦

  4. 显示图片没问题:npm run preview   使用过时的import.meta.globEager也能显示图片 ,今天更新到高版本的 vite 的glob的测过了,也没问题:高版本的vite 编写的代码如下:【缓存问题也解决了】

import storage from 'good-storage'

export class LmgLoader {

  static imgList: Record<string, any> = {}


  static async getimgList() {

    this.imgList = storage.get('imgList') || {}

    if (!LmgLoader.imgList || !LmgLoader.isNotEmptyimgList()) {

      this.imgList = LmgLoader.getImgAll()

      storage.set('imgList', LmgLoader.imgList)

    }

  }


  static isNotEmptyimgList() {

    return Object.getOwnPropertyNames(LmgLoader.imgList).length

  }

  static getImg(name: string): string {

    //console.log('name:', name)

    // LmgLoader.imgList = LmgLoader.isNotEmptyimgList() ? LmgLoader.imgList : storage.get('imgList')

    return LmgLoader.imgList[name] //

  }


  static getImgAll(): any {

    const imgList: any = {}

    const viewImgModules: Record<string, any> = import.meta.glob(`../assets/img/**/**/*.png`, { eager: true })

    // import.meta.globEager(`../assets/img/**/**/*.png`)

    for (const path in viewImgModules) {

      if (viewImgModules[path].default) {

        const pathName = path.substring(path.lastIndexOf('/') + 1)

        imgList[pathName] = viewImgModules[path].default

      }

    }

    storage.set('imgList', this.imgList)

    return imgList

  }

}


export default LmgLoader.getImg



0 回复 有任何疑惑可以回复我~
  • 老师,你说的第三点,图片路径发生改变了,删除缓存可以重新加载,这个要怎么弄?用户的我们控制不了吧,只能写上一行代码,判断有没有缓存图片,有的话就删除加载,那不是每次加载页面的时候都要删一遍在设置一遍吗?
    回复 有任何疑惑可以回复我~ 2023-04-24 22:42:58
问题已解决,确定采纳
还有疑问,暂不采纳
意见反馈 帮助中心 APP下载
官方微信