vue封装一个静态资源的文件

1. 当你在写代码时每次都会发现要去引入静态资源的图片取名字非常的麻烦还要导入,所以我们想办法简化它.

首先我们将/src/assets(注意目录是否正确)下面的资源全部导入 {svg,png,jpg}是默认格式
arduino 复制代码
const assetsFile = import.meta.glob("/src/assets/**/*.{svg,png,jpg}", {
  eager: true,
  import: "default"
});
其次我们编写一个工具函数去匹配从父组件传来的
(filePath ---> 文件路径 ---> 该值为 assets 后面的所有 目录 路径) ,
(fileName ---> 文件名) ,
(extensions ---> 文件后缀(是一个数组 ---> ["svg","png",jpg])) ,

他会去根据 后缀名数组 循环查找这个文件有没有这个文件 有的话就返回这个找到的资源 如果没有找到就抛异常

javascript 复制代码
const getAsset = () => {
  for (const ext of extensions) {
    const fullPath = `/src/assets${filePath}/${fileName}.${ext}`;
    if (assetsFile[fullPath]) {
      return defineComponent(assetsFile[fullPath]);
    }
  }
  throw new Error(`未找到匹配文件!路径: /src/assets${filePath},候选名: ${fileName},扩展名: ${extensions.join(",")}`);
};

定义从父组件接收到的值

php 复制代码
const {filePath, fileName, height, extensions} = defineProps({
  filePath: {
    type: String,
    required: true
  },
  fileName: {
    type: String as PropType<string>,
    required: true,
    description: "候选文件名数组(不带扩展名)"
  },
  height: {
    type: Number,
    default: 35
  },
  extensions: {
    type: Array as PropType<string[]>,
    default: () => ["svg", "png", "jpg"],
    description: "候选文件扩展名数组"
  }
});

2. 直接在img的src绑定这个资源文件,然后我设置了个高度默认,也可以从父组件动态的传高度,完整代码如下。

typescript 复制代码
<script setup lang="ts">
import {defineComponent, type PropType} from "vue";

const {filePath, fileName, height, extensions} = defineProps({
 filePath: {
   type: String,
   required: true
 },
 fileName: {
   type: String as PropType<string>,
   required: true,
   description: "候选文件名数组(不带扩展名)"
 },
 height: {
   type: Number,
   default: 35
 },
 extensions: {
   type: Array as PropType<string[]>,
   default: () => ["svg", "png", "jpg"],
   description: "候选文件扩展名数组"
 }
});

const assetsFile = import.meta.glob("/src/assets/**/*.{svg,png,jpg}", {
 eager: true,
 import: "default"
});

const getAsset = (): any => {
 for (const ext of extensions) {
   const fullPath = `/src/assets${filePath}/${fileName}.${ext}`;
   if (assetsFile[fullPath]) {
     return defineComponent(assetsFile[fullPath]);
   }
 }
 throw new Error(`未找到匹配文件!路径: /src/assets${filePath},候选名: ${fileName},扩展名: ${extensions.join(",")}`);
};

</script>

<template>
 <img :src="getAsset()" :height="height" alt="资源图片"/>
</template>

<style scoped></style>

3.在父组件使用它

可以看到我的filePath的值为assets(目录下) -> image(目录下) -> (svg目录),
fileName (svg/png[目录] 也可以是 ---image目录下面的任何文件目录 ---) -> 具体的某一个文件(如htmlSvg/abc)
然后传入具体的高度(默认 35 )
完整代码如下
xml 复制代码
<script setup lang="ts">

import AssetsImg from "./components/assets/AssetsImg.vue";

</script>

<template>
 <AssetsImg file-path="/image/svg" file-name="htmlSvg" :height="50"/>
 <AssetsImg file-path="/image/svg" file-name="githubSvg" :height="60"/>
 <AssetsImg file-path="/image/svg" file-name="reactSvg" :height="70"/>
 <AssetsImg file-path="/image/svg" file-name="jsSvg" :height="80"/>
  <AssetsImg file-path="/image/png" file-name="abc" :height="90"/>
</template>

<style scoped>

</style>

4.考虑到每次引用组件他都会去执行

arduino 复制代码
    const assetsFile = import.meta.glob("/src/assets/**/*.{svg,png,jpg}", {
      eager: true,
      import: "default"
    });
所以我把它抽离除去只在初始化的时候执行导入 然后页面就只需要导入这个hooks然后使用他的getAsset函数 (创建一个hooks目录来存放当前hook)
typescript 复制代码
import {defineComponent} from "vue";

const assetsFile = import.meta.glob("/src/assets/**/*.{svg,png,jpg}", {
    eager: true,
    import: "default"
})

export const useImportAssetFile = (filePath:string, fileName:string,extensions:string[]) => {
    const getAsset = (): any => {
        for (const ext of extensions) {
            const fullPath = `/src/assets${filePath}/${fileName}.${ext}`;
            if (assetsFile[fullPath]) {
                return defineComponent(assetsFile[fullPath]);
            }
        }
        throw new Error(`未找到匹配文件!路径: /src/assets${filePath},候选名: ${fileName},扩展名: ${extensions.join(",")}`);
    };

    return {
        getAsset
    }
}

如图

代码

typescript 复制代码
<script setup lang="ts">
import {type PropType} from "vue";
import {useImportAssetFile} from "./hooks/assetFile.ts";

const {filePath, fileName, height, extensions} = defineProps({
  filePath: {
    type: String,
    required: true
  },
  fileName: {
    type: String as PropType<string>,
    required: true,
    description: "候选文件名数组(不带扩展名)"
  },
  height: {
    type: Number,
    default: 35
  },
  extensions: {
    type: Array as PropType<string[]>,
    default: () => ["svg", "png", "jpg"],
    description: "候选文件扩展名数组"
  }
});

const {getAsset} = useImportAssetFile(filePath, fileName, extensions)

</script>

<template>
  <img :src="getAsset()" :height="height" alt="资源图片"/>
</template>

<style scoped></style>
相关推荐
白兰地空瓶1 小时前
🚀你以为你在写 React?其实你在“搭一套前端操作系统”
前端·react.js
爱上妖精的尾巴2 小时前
6-4 WPS JS宏 不重复随机取值应用
开发语言·前端·javascript
似水流年QC2 小时前
深入探索 WebHID:Web 标准下的硬件交互实现
前端·交互·webhid
陪我去看海2 小时前
测试 mcp
前端
speedoooo3 小时前
在现有App里嵌入一个AI协作者
前端·ui·小程序·前端框架·web app
全栈胖叔叔-瓜州3 小时前
关于llamasharp 大模型多轮对话,模型对话无法终止,或者输出角色标识User:,或者System等角色标识问题。
前端·人工智能
三七吃山漆3 小时前
攻防世界——wife_wife
前端·javascript·web安全·网络安全·ctf
用户47949283569154 小时前
面试官问"try-catch影响性能吗",我用数据打脸
前端·javascript·面试
GISer_Jing4 小时前
前端营销技术实战:数据+AI实战指南
前端·javascript·人工智能
GIS之路4 小时前
使用命令行工具 ogr2ogr 将 CSV 转换为 Shp 数据(二)
前端