refactor: 自动导入修改和项目重构优化
Former-commit-id: 100ab2e0092d96b17146163759aef897e5c14fbd
This commit is contained in:
@@ -10,10 +10,10 @@
|
||||
item.redirect === 'noredirect' || index === breadcrumbs.length - 1
|
||||
"
|
||||
class="text-[#97a8be]"
|
||||
>{{ generateTitle(item.meta.title) }}</span
|
||||
>{{ translateRouteTitleI18n(item.meta.title) }}</span
|
||||
>
|
||||
<a v-else @click.prevent="handleLink(item)">
|
||||
{{ generateTitle(item.meta.title) }}
|
||||
{{ translateRouteTitleI18n(item.meta.title) }}
|
||||
</a>
|
||||
</el-breadcrumb-item>
|
||||
</transition-group>
|
||||
@@ -25,7 +25,7 @@ import { onBeforeMount, ref, watch } from 'vue';
|
||||
import { useRoute, RouteLocationMatched } from 'vue-router';
|
||||
import { compile } from 'path-to-regexp';
|
||||
import router from '@/router';
|
||||
import { generateTitle } from '@/utils/i18n';
|
||||
import { translateRouteTitleI18n } from '@/utils/i18n';
|
||||
|
||||
const currentRoute = useRoute();
|
||||
const pathCompile = (path: string) => {
|
||||
|
||||
@@ -1,92 +1,84 @@
|
||||
<template>
|
||||
<div class="icon-select">
|
||||
<el-input
|
||||
v-model="iconName"
|
||||
clearable
|
||||
placeholder="请输入图标名称"
|
||||
@clear="filterIcons"
|
||||
@input="filterIcons"
|
||||
>
|
||||
<template #suffix><i class="el-icon-search el-input__icon" /></template>
|
||||
</el-input>
|
||||
<div class="icon-select__list">
|
||||
<div
|
||||
v-for="(item, index) in iconList"
|
||||
:key="index"
|
||||
@click="selectedIcon(item)"
|
||||
>
|
||||
<svg-icon
|
||||
color="#999"
|
||||
:icon-class="item"
|
||||
style="height: 30px; width: 16px; margin-right: 5px"
|
||||
/>
|
||||
<span>{{ item }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
import SvgIcon from '@/components/SvgIcon/index.vue';
|
||||
const props = defineProps({
|
||||
modelValue: {
|
||||
type: String,
|
||||
require: false
|
||||
}
|
||||
});
|
||||
|
||||
const icons = [] as string[];
|
||||
const modules = import.meta.glob('../../assets/icons/*.svg');
|
||||
for (const path in modules) {
|
||||
const p = path.split('assets/icons/')[1].split('.svg')[0];
|
||||
icons.push(p);
|
||||
}
|
||||
const iconList = ref(icons);
|
||||
const emit = defineEmits(['update:modelValue']);
|
||||
const visible = ref(false);
|
||||
const inputValue = toRef(props, 'modelValue');
|
||||
const iconList = ref<string[]>([]);
|
||||
|
||||
const iconName = ref('');
|
||||
const filterValue = ref('');
|
||||
|
||||
const emit = defineEmits(['selected']);
|
||||
const icon = ref('perm');
|
||||
|
||||
function filterIcons() {
|
||||
iconList.value = icons;
|
||||
if (iconName.value) {
|
||||
iconList.value = icons.filter(item => item.indexOf(iconName.value) !== -1);
|
||||
function loadIcons() {
|
||||
const modules = import.meta.glob('../../assets/icons/*.svg');
|
||||
for (const path in modules) {
|
||||
const icon = path.split('assets/icons/')[1].split('.svg')[0];
|
||||
iconList.value.push(icon);
|
||||
}
|
||||
}
|
||||
|
||||
function selectedIcon(name: string) {
|
||||
emit('selected', name);
|
||||
document.body.click();
|
||||
}
|
||||
|
||||
function reset() {
|
||||
iconName.value = '';
|
||||
iconList.value = icons;
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
reset
|
||||
onMounted(() => {
|
||||
loadIcons();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.icon-select {
|
||||
width: 100%;
|
||||
padding: 10px;
|
||||
<template>
|
||||
<div class="w-[400px] relative">
|
||||
<el-input v-model="inputValue" readonly>
|
||||
<template #prepend> <svg-icon :iconName="icon"></svg-icon> </template>
|
||||
</el-input>
|
||||
|
||||
&__list {
|
||||
height: 200px;
|
||||
overflow-y: scroll;
|
||||
<el-popover
|
||||
shadow="none"
|
||||
:visible="visible"
|
||||
placement="bottom-end"
|
||||
trigger="click"
|
||||
>
|
||||
<template #reference>
|
||||
<div
|
||||
@click="visible = !visible"
|
||||
class="cursor-pointer text-[#999] absolute right-[10px] top-0"
|
||||
>
|
||||
<i-ep-caret-top v-show="visible"></i-ep-caret-top>
|
||||
<i-ep-caret-bottom v-show="!visible"></i-ep-caret-bottom>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
div {
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
margin-bottom: -5px;
|
||||
cursor: pointer;
|
||||
width: 33%;
|
||||
float: left;
|
||||
}
|
||||
<!-- 下拉选择弹窗 -->
|
||||
<el-input
|
||||
class="p-2"
|
||||
v-model="filterValue"
|
||||
placeholder="搜索图标"
|
||||
clearable
|
||||
/>
|
||||
<el-divider border-style="dashed" />
|
||||
|
||||
span {
|
||||
display: inline-block;
|
||||
vertical-align: -0.15em;
|
||||
fill: currentColor;
|
||||
overflow: hidden;
|
||||
<el-scrollbar height="300px">
|
||||
<ul class="icon-list">
|
||||
<li class="icon-item" v-for="(item, index) in iconList" :key="index">
|
||||
<svg-icon color="#999" :icon-name="item" />
|
||||
<span>{{ item }}</span>
|
||||
</li>
|
||||
</ul>
|
||||
</el-scrollbar>
|
||||
</el-popover>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.icon-list {
|
||||
.icon-item {
|
||||
&:hover {
|
||||
border-color: var(--el-color-primary);
|
||||
color: var(--el-color-primary);
|
||||
transition: all 0.4s;
|
||||
transform: scaleX(1.05);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div :class="{ hidden: hidden }" class="pagination-container">
|
||||
<div :class="'pagination ' + { hidden: hidden }">
|
||||
<el-pagination
|
||||
:background="background"
|
||||
v-model:current-page="currentPage"
|
||||
@@ -89,13 +89,11 @@ function handleCurrentChange(val: number) {
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.pagination-container {
|
||||
background: #fff;
|
||||
padding: 32px 16px;
|
||||
}
|
||||
|
||||
.pagination-container.hidden {
|
||||
display: none;
|
||||
<style lang="scss" scoped>
|
||||
.pagination {
|
||||
padding: 12px;
|
||||
&.hidden {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="cursor-pointer w-[40px] h-[50px] leading-[50px] text-center">
|
||||
<svg-icon
|
||||
:icon-class="isFullscreen ? 'exit-fullscreen' : 'fullscreen'"
|
||||
:icon-name="isFullscreen ? 'exit-fullscreen' : 'fullscreen'"
|
||||
@click="toggle"
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -22,7 +22,7 @@ function handleSizeChange(size: string) {
|
||||
<template>
|
||||
<el-dropdown trigger="click" @command="handleSizeChange">
|
||||
<div class="cursor-pointerw-[40px] h-[50px] leading-[50px] text-center">
|
||||
<svg-icon icon-class="size" />
|
||||
<svg-icon icon-name="size" />
|
||||
</div>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
|
||||
@@ -9,14 +9,12 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
|
||||
const props = defineProps({
|
||||
prefix: {
|
||||
type: String,
|
||||
default: 'icon'
|
||||
},
|
||||
iconClass: {
|
||||
iconName: {
|
||||
type: String,
|
||||
required: false
|
||||
},
|
||||
@@ -29,12 +27,15 @@ const props = defineProps({
|
||||
}
|
||||
});
|
||||
|
||||
const symbolId = computed(() => `#${props.prefix}-${props.iconClass}`);
|
||||
const symbolId = computed(() => `#${props.prefix}-${props.iconName}`);
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.svg-icon {
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
vertical-align: -0.15em; /* 因icon大小被设置为和字体大小一致,而span等标签的下边缘会和字体的基线对齐,故需设置一个往下的偏移比例,来纠正视觉上的未对齐效果 */
|
||||
fill: currentColor; /* 定义元素的颜色,currentColor是一个变量,这个变量的值就表示当前元素的color值,如果当前元素未设置color值,则从父元素继承 */
|
||||
overflow: hidden;
|
||||
fill: currentColor;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -15,10 +15,7 @@
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useSettingsStore } from '@/store/modules/settings';
|
||||
const settingsStore = useSettingsStore();
|
||||
</script>
|
||||
<script setup lang="ts"></script>
|
||||
|
||||
<style>
|
||||
.theme-message,
|
||||
|
||||
@@ -11,20 +11,18 @@
|
||||
:before-upload="handleBeforeUpload"
|
||||
:http-request="handleUpload"
|
||||
:on-remove="handleRemove"
|
||||
:on-preview="handlePreview"
|
||||
:on-preview="previewImg"
|
||||
:limit="props.limit"
|
||||
>
|
||||
<el-icon><Plus /></el-icon>
|
||||
<i-ep-plus />
|
||||
</el-upload>
|
||||
|
||||
<el-dialog v-model="dialogVisible">
|
||||
<img w-full :src="dialogImageUrl" alt="Preview Image" />
|
||||
<img w-full :src="previewImgUrl" alt="Preview Image" />
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, watch } from 'vue';
|
||||
import { Plus } from '@element-plus/icons-vue';
|
||||
import {
|
||||
ElMessage,
|
||||
ElUpload,
|
||||
@@ -55,7 +53,7 @@ const props = defineProps({
|
||||
}
|
||||
});
|
||||
|
||||
const dialogImageUrl = ref('');
|
||||
const previewImgUrl = ref('');
|
||||
const dialogVisible = ref(false);
|
||||
|
||||
const fileList = ref([] as UploadUserFile[]);
|
||||
@@ -134,10 +132,10 @@ function handleBeforeUpload(file: UploadRawFile) {
|
||||
}
|
||||
|
||||
/**
|
||||
* 图片预览
|
||||
* 预览图片
|
||||
*/
|
||||
const handlePreview: UploadProps['onPreview'] = uploadFile => {
|
||||
dialogImageUrl.value = uploadFile.url!;
|
||||
const previewImg: UploadProps['onPreview'] = uploadFile => {
|
||||
previewImgUrl.value = uploadFile.url!;
|
||||
dialogVisible.value = true;
|
||||
};
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user