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>
相关推荐
乔冠宇5 分钟前
CSS3中的新增属性总结
前端·javascript·css3
e***58235 分钟前
Spring Cloud GateWay搭建
android·前端·后端
青衫码上行1 小时前
【Java Web学习 | 第15篇】jQuery(万字长文警告)
java·开发语言·前端·学习·jquery
x***13393 小时前
【MyBatisPlus】MyBatisPlus介绍与使用
android·前端·后端
z***75156 小时前
【Springboot3+vue3】从零到一搭建Springboot3+vue3前后端分离项目之后端环境搭建
android·前端·后端
fruge7 小时前
仿写优秀组件:还原 Element Plus 的 Dialog 弹窗核心逻辑
前端
an86950017 小时前
vue新建项目
前端·javascript·vue.js
w***95497 小时前
SQL美化器:sql-beautify安装与配置完全指南
android·前端·后端
顾安r8 小时前
11.22 脚本打包APP 排错指南
linux·服务器·开发语言·前端·flask
万邦科技Lafite8 小时前
1688图片搜索商品API接口(item_search_img)使用指南
java·前端·数据库·开放api·电商开放平台