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>