Vue2、Vue3 动态引用静态资源

1,896 阅读3分钟

vue2+webpack

在vue2中,可以使用 require 以模块的方式动态引入资源文件,webpack会将 require 引入的模块进行打包编译。

// 正常引入assets静态资源
<img width="16" src="@/assets/images/file.png" alt="描述性文本" />

如果图片无法显示,浏览器将会显示alt属性中的文本,这有助于提高网站的可访问性。

require 动态引入

<img :src="require('@/assets/images' + item.icon.toLowerCase() + '.png')" alt="" />

<img :src="require(`@/assets/images/${icon}.${isPng ? 'png' : 'svg'}`)" alt="">
<img :src="imageSrc('icon)" alt="" />

imageSrc(imageName) {
    return require(`@/assets/images/${imageName}.png`);
}
<img :src="urlPrefix() + '/images/demo.png" alt="" />

// 获取url前缀地址
urlPrefix() {
      const origin = '';
      return origin ? `${origin}/static` : '';
}

动态添加背景图片

在添加背景图片时,可以使用图片名称作为动态参数,提取公共方法完成样式处理。

<div :style="setStyle('imgName')">添加背景图片</div>
<div :style="setStyle(active === 'first' ? 'active_bg' : 'bg')"></div>

methods: {
  setStyle(name) {
    return `
      background-image: url(${require(`@/assets/images/${name}.png`)});
      background-size: 100% 100%;
    `;
  }

vue3+vite

vue2中可以使用require动态引入图片,但在开发vue3+vite项目的时候,使用require 会报错 require is not defind。因为require是webpack的方法,vite是不支持的。

import 引入(适用于单个资源文件)

import homeBg from 'src/assets/images/home/home_bg.png'
 
<img :src="homeBg" />

如果引用资源不多,也可以逐一引入使用

new URL() + import.meta.url(适用于多个资源文件)

(1)在src/util目录下创建一个utils.js文件

// 获取assets静态资源,动态传入文件路径
export const getAssetsFile = (url: string) => {
      return new URL(`../assets/images/${url}`, import.meta.url).href;
};

(2)在vue文件中导入并使用

import { getAssetsFile } from 'src/util/utils';

<img class="bg-img" :src="getAssetsFile('bg.png')" alt=""> 

import.meta.glob (官方提供API)

(1) 指定具体文件夹路径,传入的变量为文件名、文件类型

export const getAssetsFile = (fileName: string, type = 'png') => {
      const path = `/src/assets/images/${fileName}.${type}`;
      const modules: Record<string, any> = import.meta.glob("@/assets/images/*.{png,svg,jpg,jpeg}", { eager: true });
      if (modules[path]) return modules[path].default;
      else {
        // 地址错误
        console.error("Error url is wrong path");
      }
};

(2)动态设置文件路径,传入的变量为文件名、文件路径、文件类型

const getAssetsFile = (url: string, folder = null, type = 'png') => {
      const path = folder ? `/src/assets/images/${folder}/${url}.${type}` : `/src/assets/images/${url}.${type}`;
      const modules: Record<string, any> = import.meta.glob(`@/assets/images/**/*.{png,svg,jpg,jpeg}`, { eager: true });
      if (modules[path]) return modules[path].default;
      ……
};

public+绝对路径

把所有静态资源放到public/目录下,引用的资源路径改为绝对路径并去掉public前缀。如:引入 public/static/home/首页.png,直接使用 /static/home/首页.png 即可。

原理:

在Vite中, / 开头的绝对路径默认可以访问到 public/ 目录下的内容,所以 /public/static/home/首页.png 和 /static/home/首页.png 都可以访问到本地资源。

但在打包时,Vite默认会原样保留绝对路径的引用地址,但不会保留public文件夹,即public下的static文件夹会被直接输出到dist/目录下,而没有public文件夹了。

所以虽然这两种都可以访问到本地资源,但是考虑到默认的打包处理方式,还是要去除掉/public前缀才能保证打包之后也可以正常引入静态资源。

背景图片引入

.bg-box{
      background-image: url('../../assets/images/bg.png');
}

结束语

静态资源可以通过两种方式进行处理:

  • 在 JavaScript 被导入或在 template/CSS 中通过相对路径被引用。这类引用会被 webpack 处理。

  • 放置在 public 目录下或通过绝对路径被引用。这类资源将会直接被拷贝,而不会经过 webpack 的处理。

    webpack或vite,将代码编译后最终会构造出一个类似于打包后的dist文件,会将普通方式图片路径编译转化成dist/img文件夹下的资源。所有没有编译过的图片路径是访问不到的,这也是动态直接加载图片路径渲染不出来的原因

    在public文件夹下的图片,不管是webpack还是vite都不会进行编译,在该文件夹下的路径是一个绝对路径,所以不管是普通引用还是动态加载图片都不会有问题。

参考学习

blog.csdn.net/weixin_4374…
blog.csdn.net/Andye11/art…