背景:

文章讲述了Vite框架中引入图片等静态资源,遇见的问题,和vite脚手架的版本有关。例如:vite5框架的项目在开发和生产环境都可以使用,但是在vite6框架搭建的项目,在开发环境就不可以使用,在生产环境也不可以使用即使在开发环境,把字符串使用一个url变量替换后,在开发环境图片能够加载出来;但是打包后部署到到生产环境,在生产环境图片不能够加载出来。因为打包后的图片地址的src和开发环境的src是一样的【图片如下】,这两个src都是形如:../assets/images/video/video_icon1.png这样的一个字符串,导致在生产环境的时候,图片绑定的src不能够加载出来【开发环境和部署环境是不一样的】。

在默认配置下,如何正确处理开发环境和打包后的不同引用方式。本文重点介绍了使用import.meta.url和new URL() 来动态获取并处理静态资源URL的方法,以及在vite5和vite6不同版本使用此方法遇见的问题,以及对vite6引入不出来的解决办法。

问题解决前,效果展示:

问题解决后,效果展示:

核心思路: 

new URL(`../assets/images/${name}`, import.meta.url).href

使用原生的new URL() 实现静态资源的动态引入

核心代码:

//封装方法
export const getAssetsFile = (name) => {
	return new URL(`../assets/images/${name}`, import.meta.url).href;
};

 调用封装的方法:

//调用封装的getAssetsFile()方法
//最前面不带/
<img :src="getAssetsFile('video/video_icon1')" />

写到这儿,功能就实现了,以下是具体项目中遇到的问题。。。 

一、vue3+vite5有效 

封装方法:

//封装方法
export const getAssetsFile = (name) => {
	return new URL(`../assets/images/${name}`, import.meta.url).href;
};

静态图片放在src文件夹下的具体位置:../assets/images/video/video_icon1.png

//调用封装的getAssetsFile()方法
//最前面不带/
<img :src="getAssetsFile('video/video_icon1')" />

开发环境,控制台打印:

二、vue3+vite6无效

(一)、vue3+vite6无效

封装方法:

new URL(url变量,import.meta.url) .herf

//封装方法
export const getAssetsFile = (name) => {
	const url = `../assets/images/${name}`;
	return new URL(url, import.meta.url).href;
};

开发环境,控制台打印:

(二)、解决办法  

问题描述:

之前能够使用,但是最新创建的项目就不能使用,图片如下:

 解决方式一:用一个变量url替换字符串

虽然不知道为什么,但是好在页面上显示出来了【在开发环境显示,打包部署后不显示】:

 解决方式二:将资源引入为URL

<img :src="upIcon" />
import upIcon from "@/assets/images/table/upload.png";

解决方式三: 不支持子目录,那么改成不断添加新的子目录

当图片资源存放在多层文件夹下,此时 path 路径含有多层目录,无法获得资源地址。

封装代码如下: 

/**
 * 获取图片的地址
 * @param path 基于assets/images/文件夹下的位置
 * @returns 图片地址
 */
export function getImageUrl(path: string) {
  const index = path.lastIndexOf('/');
  if (index !== -1) {
    const startWith = path.substring(0, index);
    const imageName = path.substring(index + 1);
    switch (startWith) {
      case '404_images':
        return get404ImagesUrl(imageName);
      // 不断添加新的子目录即可
    }
  } else {
    return new URL(`../assets/images/${path}`, import.meta.url).href;
  }
}
 
/**
 * 获取404_images文件夹下图片的地址
 * @param name 基于assets/images/404_images文件夹下的图片名称
 * @returns 图片地址
 */
export function get404ImagesUrl(name: string) {
  return new URL(`../assets/images/404_images/${name}`, import.meta.url).href;
}

 (三)、原因分析

vite3的支持:点击跳转vite3

 

vite6的不支持:点击跳转vite6

 

以下是一些理论知识。。。 

 三、import.meta和new URL理论知识

(一)、import.meta是详细介绍:

参考链接:import.meta的详细介绍

import.meta是一个 ESM 的原生功能,会暴露当前模块的 URL。import.meta 元属性将特定上下文的元数据暴露给 JavaScript 模块。它包含了这个模块的信息,例如这个模块的 URL。

1.语法:

import.meta

2.值

url

到此模块的完整 URL,包括查询参数和片段标识符(在 ? 和 # 之后)。在浏览器中,它是可获取此脚本的 URL(对外部脚本)或者是包含此脚本的文档的 URL(对内联脚本)。在 Node.js 中,它是文件路径(包括 file:// 协议部分)。

import.meta.url

 

 (二)、new URL(url,import.meta.url)的详细介绍

参考链接:点击跳转​​​​​​​

URL() 构造函数返回一个新创建的URL对象,该对象表示由参数定义的 URL。

1.语法:

new URL(url)
new URL(url, base)
2.两个参数代表的含义:

url

一个表示绝对或相对 URL 的 DOMString或任何具有字符串化方法的对象,例如 <a>或 <area>元素。如果 url 是相对 URL,则会将 base 用作基准 URL。如果 url 是绝对 URL,则无论参数 base 是否存在,都将被忽略。

base【可选】

一个表示基准 URL 的字符串,当 url 为相对 URL 时,它才会生效。如果未指定,它默认为 undefined

vite官网链接:vite官网的参考链接

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐