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>
相关推荐
GreenTea10 分钟前
一文搞懂Harness Engineering与Meta-Harness
前端·人工智能·后端
killerbasd2 小时前
牧苏苏传 我不装了 4/7
前端·javascript·vue.js
吴声子夜歌2 小时前
ES6——二进制数组详解
前端·ecmascript·es6
码事漫谈2 小时前
手把手带你部署本地模型,让你Token自由(小白专属)
前端·后端
ZC跨境爬虫2 小时前
【爬虫实战对比】Requests vs Scrapy 笔趣阁小说爬虫,从单线程到高效并发的全方位升级
前端·爬虫·scrapy·html
爱上好庆祝2 小时前
svg图片
前端·css·学习·html·css3
王夏奇3 小时前
python中的__all__ 具体用法
java·前端·python
大家的林语冰3 小时前
《前端周刊》尤大开源 Vite+ 全家桶,前端工业革命启动;尤大爆料 Void 云服务新产品,Vite 进军全栈开发;ECMA 源码映射规范......
前端·javascript·vue.js
jiayong234 小时前
第 8 课:开始引入组合式函数
前端·javascript·学习
田八4 小时前
聊聊AI的发展史,AI的爆发并不是偶然
前端·人工智能·程序员