feat: 添加图标和路由配置
- 新增多个 SVG 图标文件 - 添加 `/demo/icons` 路由配置,用于图标预览
This commit is contained in:
119
src/views/demo/icons.vue
Normal file
119
src/views/demo/icons.vue
Normal file
@ -0,0 +1,119 @@
|
||||
<template>
|
||||
<div class="xt-icons-container">
|
||||
<h2>通用类 SVG 图标</h2>
|
||||
<p class="tips mt4">点击「图标」复制SVG</p>
|
||||
|
||||
<div class="icons-grid">
|
||||
<div
|
||||
v-for="iconName in xtIconNames"
|
||||
:key="iconName"
|
||||
class="icon-item cursor-pointer"
|
||||
@click="onCopySvg(iconName)"
|
||||
>
|
||||
<SvgIcon :name="iconName" class="mb-12px" size="24" />
|
||||
<TextOverTips :context="iconName" class="icon-name text-center" line="1" placement="bottom" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2 style="margin-top: 40px">非通用类 SVG 图标</h2>
|
||||
<div class="icons-grid">
|
||||
<div
|
||||
v-for="iconName in otherIconNames"
|
||||
:key="iconName"
|
||||
class="icon-item cursor-pointer"
|
||||
@click="onCopySvg(iconName)"
|
||||
>
|
||||
<SvgIcon :name="iconName" class="mb-12px" size="24" />
|
||||
<TextOverTips :context="iconName" class="icon-name text-center" line="1" placement="bottom" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { message } from 'ant-design-vue';
|
||||
import SvgIcon from '@/components/svg-icon/index.vue';
|
||||
import TextOverTips from '@/components/text-over-tips';
|
||||
|
||||
import { ref, onMounted } from 'vue';
|
||||
import { useClipboard } from '@vueuse/core';
|
||||
|
||||
const xtIconNames = ref([]);
|
||||
const otherIconNames = ref([]);
|
||||
const { copy } = useClipboard();
|
||||
|
||||
// 动态获取所有图标名称,并区分 xt 前缀和非 xt 前缀的图标
|
||||
const getAllIcons = () => {
|
||||
// 使用 import.meta.glob 动态导入所有 svg 文件
|
||||
const allSvgModules = import.meta.glob('@/assets/svg/*.svg');
|
||||
|
||||
// 从文件路径中提取文件名(不包含扩展名)
|
||||
const allIconNames = Object.keys(allSvgModules).map((path) => {
|
||||
const fileName = path.split('/').pop(); // 获取文件名
|
||||
return fileName.replace('.svg', ''); // 去掉扩展名
|
||||
});
|
||||
|
||||
// 区分 xt 前缀和非 xt 前缀的图标
|
||||
const xtIcons = [];
|
||||
const otherIcons = [];
|
||||
|
||||
allIconNames.forEach((iconName) => {
|
||||
if (iconName.startsWith('xt-')) {
|
||||
xtIcons.push(iconName);
|
||||
} else {
|
||||
otherIcons.push(iconName);
|
||||
}
|
||||
});
|
||||
|
||||
return { xtIcons, otherIcons };
|
||||
};
|
||||
|
||||
const onCopySvg = (name) => {
|
||||
const context = `<SvgIcon name="${name}" size="14" class="color-#55585f"/>`;
|
||||
copy(context);
|
||||
message.success('复制成功');
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
const { xtIcons, otherIcons } = getAllIcons();
|
||||
xtIconNames.value = xtIcons;
|
||||
otherIconNames.value = otherIcons;
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.xt-icons-container {
|
||||
padding: 20px;
|
||||
|
||||
.icons-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(130px, 1fr));
|
||||
gap: 20px;
|
||||
margin-top: 20px;
|
||||
|
||||
.icon-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: 10px;
|
||||
border-radius: 8px;
|
||||
background-color: #fff;
|
||||
color: #737478;
|
||||
transition: all 0.3s ease;
|
||||
|
||||
&:hover {
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.icon-name {
|
||||
color: var(--Text-2, #55585f);
|
||||
font-family: $font-family-regular;
|
||||
font-size: 12px;
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
line-height: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user