refactor: 自动导入修改和项目重构优化

Former-commit-id: 100ab2e0092d96b17146163759aef897e5c14fbd
This commit is contained in:
haoxr
2023-01-13 01:05:45 +08:00
parent 0ae7e0da92
commit 9522875198
36 changed files with 881 additions and 386 deletions

View File

@@ -1,16 +1,6 @@
<script setup lang="ts">
import { computed } from 'vue';
import { storeToRefs } from 'pinia';
import { useRoute, useRouter } from 'vue-router';
import { ElMessageBox } from 'element-plus';
import Hamburger from '@/components/Hamburger/index.vue';
import Breadcrumb from '@/components/Breadcrumb/index.vue';
import Screenfull from '@/components/Screenfull/index.vue';
import SizeSelect from '@/components/SizeSelect/index.vue';
import LangSelect from '@/components/LangSelect/index.vue';
import MixNav from './Sidebar/MixNav.vue';
import { CaretBottom } from '@element-plus/icons-vue';
import { useAppStore } from '@/store/modules/app';
import { useTagsViewStore } from '@/store/modules/tagsView';
import { useUserStore } from '@/store/modules/user';
@@ -24,12 +14,14 @@ const settingsStore = useSettingsStore();
const route = useRoute();
const router = useRouter();
const device = computed(() => appStore.device);
const { device } = storeToRefs(appStore); // 设备类型desktop-宽屏设备 || mobile-窄屏设备
const { layout } = storeToRefs(settingsStore); // 布局模式left-左侧模式||top-顶部模式||mix-混合模式
function toggleSideBar() {
appStore.toggleSidebar(true);
}
// 注销
function logout() {
ElMessageBox.confirm('确定注销并退出系统吗?', '提示', {
confirmButtonText: '确定',
@@ -52,7 +44,7 @@ function logout() {
<div class="navbar">
<div
class="flex justify-start"
v-if="device === 'mobile' || settingsStore.layout === 'left'"
v-if="device === 'mobile' || layout === 'left'"
>
<hamburger
:is-active="appStore.sidebar.opened"
@@ -62,13 +54,24 @@ function logout() {
<breadcrumb />
</div>
<mix-nav v-if="device !== 'mobile' && settingsStore.layout === 'mix'" />
<mix-nav v-if="device !== 'mobile' && layout === 'mix'" />
<!-- 宽屏或左侧模式显示 -->
<div
v-if="device === 'mobile' || settingsStore.layout === 'left'"
v-if="device === 'desktop' || layout === 'left'"
class="flex justify-start"
>
<!-- 左侧窄屏不显示 -->
<div v-if="device !== 'mobile'" class="flex justify-center items-center">
<i-ep-add-location />
<i-ep-aim />
<div i-ep-check />
<el-button>
<template #icon><i-ep-circle-check-filled /></template>
Hello world
</el-button>
<!--全屏 -->
<screenfull id="screenfull" />
@@ -80,14 +83,14 @@ function logout() {
<!--语言选择-->
<lang-select />
</div>
<!-- 头像 -->
<el-dropdown trigger="click">
<div class="flex justify-center items-center pr-[20px]">
<img
:src="userStore.avatar + '?imageView2/1/w/80/h/80'"
class="w-[40px] h-[40px] rounded-lg"
/>
<CaretBottom class="w-3 h-3" />
<i-ep-caret-bottom class="w-3 h-3" />
</div>
<template #dropdown>
@@ -115,15 +118,12 @@ function logout() {
</template>
<style lang="scss" scoped>
.el-dropdown {
font-size: 18px;
}
.navbar {
background-color: #fff;
height: 50px;
display: flex;
align-items: center;
justify-content: space-between;
box-shadow: 0 0px 2px rgba(0, 0, 0, 0.2);
box-shadow: 0 0 1px #0003;
}
</style>

View File

@@ -3,7 +3,7 @@ import { computed } from 'vue';
import { isExternal } from '@/utils/validate';
import { useRouter } from 'vue-router';
import { DeviceType, useAppStore } from '@/store/modules/app';
import { useAppStore } from '@/store/modules/app';
const appStore = useAppStore();
const sidebar = computed(() => appStore.sidebar);

View File

@@ -1,6 +1,6 @@
<script setup lang="ts">
import { computed, onMounted } from 'vue';
import { RouterLink, useRoute, useRouter, RouteRecordRaw } from 'vue-router';
import { RouterLink, useRoute, useRouter } from 'vue-router';
import {
ElDropdown,
ElDropdownItem,

View File

@@ -4,7 +4,7 @@ import path from 'path-browserify';
import { isExternal } from '@/utils/validate';
import AppLink from './Link.vue';
import { generateTitle } from '@/utils/i18n';
import { translateRouteTitleI18n } from '@/utils/i18n';
import SvgIcon from '@/components/SvgIcon/index.vue';
const props = defineProps({
@@ -78,10 +78,10 @@ function resolvePath(routePath: string) {
>
<svg-icon
v-if="onlyOneChild.meta && onlyOneChild.meta.icon"
:icon-class="onlyOneChild.meta.icon"
:icon-name="onlyOneChild.meta.icon"
/>
<template #title>
{{ generateTitle(onlyOneChild.meta.title) }}
{{ translateRouteTitleI18n(onlyOneChild.meta.title) }}
</template>
</el-menu-item>
</app-link>
@@ -92,10 +92,10 @@ function resolvePath(routePath: string) {
<template #title>
<svg-icon
v-if="item.meta && item.meta.icon"
:icon-class="item.meta.icon"
:icon-name="item.meta.icon"
/>
<span v-if="item.meta && item.meta.title">{{
generateTitle(item.meta.title)
translateRouteTitleI18n(item.meta.title)
}}</span>
</template>

View File

@@ -1,11 +1,4 @@
<script setup lang="ts">
import {
ref,
computed,
onMounted,
onBeforeUnmount,
getCurrentInstance
} from 'vue';
import { useTagsViewStore, TagView } from '@/store/modules/tagsView';
const tagAndTagSpacing = ref(4);
@@ -102,8 +95,8 @@ defineExpose({
<template>
<el-scrollbar
ref="scrollContainer"
:vertical="false"
class="scroll-container"
:vertical="false"
@wheel.prevent="handleScroll"
>
<slot />

View File

@@ -7,26 +7,27 @@ import {
onMounted,
ComponentInternalInstance
} from 'vue';
import { storeToRefs } from 'pinia';
import path from 'path-browserify';
import { useRoute, useRouter } from 'vue-router';
import ScrollPane from './ScrollPane.vue';
import SvgIcon from '@/components/SvgIcon/index.vue';
import { generateTitle } from '@/utils/i18n';
import { translateRouteTitleI18n } from '@/utils/i18n';
import { usePermissionStore } from '@/store/modules/permission';
import { useTagsViewStore, TagView } from '@/store/modules/tagsView';
const permissionStore = usePermissionStore();
const tagsViewStore = useTagsViewStore();
import ScrollPane from './ScrollPane.vue';
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const router = useRouter();
const route = useRoute();
const visible = ref(false);
const permissionStore = usePermissionStore();
const tagsViewStore = useTagsViewStore();
const { visitedViews } = storeToRefs(tagsViewStore);
const selectedTag = ref({});
const scrollPaneRef = ref();
const left = ref(0);
@@ -45,11 +46,12 @@ watch(
}
);
watch(visible, value => {
const tagMenuVisible = ref(false); // 标签操作菜单显示状态
watch(tagMenuVisible, value => {
if (value) {
document.body.addEventListener('click', closeMenu);
document.body.addEventListener('click', closeTagMenu);
} else {
document.body.removeEventListener('click', closeMenu);
document.body.removeEventListener('click', closeTagMenu);
}
});
@@ -78,11 +80,11 @@ function filterAffixTags(routes: any[], basePath = '/') {
}
function initTags() {
const tags = filterAffixTags(permissionStore.routes);
const tags: TagView[] = filterAffixTags(permissionStore.routes);
affixTags.value = tags;
for (const tag of tags) {
// Must have tag name
if ((tag as TagView).name) {
if (tag.name) {
tagsViewStore.addVisitedView(tag);
}
}
@@ -205,7 +207,7 @@ function closeAllTags(view: TagView) {
});
}
function openMenu(tag: TagView, e: MouseEvent) {
function openTagMenu(tag: TagView, e: MouseEvent) {
const menuMinWidth = 105;
const offsetLeft = proxy?.$el.getBoundingClientRect().left; // container margin left
const offsetWidth = proxy?.$el.offsetWidth; // container width
@@ -219,16 +221,16 @@ function openMenu(tag: TagView, e: MouseEvent) {
}
top.value = e.clientY;
visible.value = true;
tagMenuVisible.value = true;
selectedTag.value = tag;
}
function closeMenu() {
visible.value = false;
function closeTagMenu() {
tagMenuVisible.value = false;
}
function handleScroll() {
closeMenu();
closeTagMenu();
}
onMounted(() => {
@@ -237,71 +239,71 @@ onMounted(() => {
</script>
<template>
<div
class="h-[34px] w-full border-b-[1px] border-gray-200 shadow-lg shadow-[rgba(0, 21, 41, 0.08)]"
<scroll-pane
class="tags-container"
ref="scrollPaneRef"
@scroll="handleScroll"
>
<scroll-pane
ref="scrollPaneRef"
class="tags-container"
@scroll="handleScroll"
<router-link
:class="'tags-item ' + (isActive(tag) ? 'active' : '')"
v-for="tag in visitedViews"
:key="tag.path"
:data-path="tag.path"
:to="{ path: tag.path, query: tag.query }"
@click.middle="!isAffix(tag) ? closeSelectedTag(tag) : ''"
@contextmenu.prevent="openTagMenu(tag, $event)"
>
<router-link
v-for="tag in tagsViewStore.visitedViews"
:key="tag.path"
:data-path="tag.path"
:class="isActive(tag) ? 'active' : ''"
:to="{ path: tag.path, query: tag.query }"
class="tags-item"
@click.middle="!isAffix(tag) ? closeSelectedTag(tag) : ''"
@contextmenu.prevent="openMenu(tag, $event)"
{{ translateRouteTitleI18n(tag.meta?.title) }}
<span
v-if="!isAffix(tag)"
class="rounded-[60%] hover:bg-gray-300"
@click.prevent.stop="closeSelectedTag(tag)"
>
{{ generateTitle(tag.meta?.title) }}
<i-ep-close class="text-[10px]" />
</span>
</router-link>
</scroll-pane>
<span
v-if="!isAffix(tag)"
class="tags-item-remove"
@click.prevent.stop="closeSelectedTag(tag)"
>
<svg-icon icon-class="close" />
</span>
</router-link>
</scroll-pane>
<ul
v-show="visible"
:style="{ left: left + 'px', top: top + 'px' }"
class="tags-item-menu"
>
<li @click="refreshSelectedTag(selectedTag)">
<svg-icon icon-class="refresh" />
刷新
</li>
<li v-if="!isAffix(selectedTag)" @click="closeSelectedTag(selectedTag)">
<svg-icon icon-class="close" />
关闭
</li>
<li @click="closeOtherTags">
<svg-icon icon-class="close_other" />
关闭其它
</li>
<li v-if="!isFirstView()" @click="closeLeftTags">
<svg-icon icon-class="close_left" />
关闭左侧
</li>
<li v-if="!isLastView()" @click="closeRightTags">
<svg-icon icon-class="close_right" />
关闭右侧
</li>
<li @click="closeAllTags(selectedTag)">
<svg-icon icon-class="close_all" />
关闭所有
</li>
</ul>
</div>
<!-- tag标签操作菜单 -->
<ul
v-show="tagMenuVisible"
class="tag-menu"
:style="{ left: left + 'px', top: top + 'px' }"
>
<li @click="refreshSelectedTag(selectedTag)">
<svg-icon icon-name="refresh" />
刷新
</li>
<li v-if="!isAffix(selectedTag)" @click="closeSelectedTag(selectedTag)">
<svg-icon icon-name="close" />
关闭
</li>
<li @click="closeOtherTags">
<svg-icon icon-name="close_other" />
关闭其它
</li>
<li v-if="!isFirstView()" @click="closeLeftTags">
<svg-icon icon-name="close_left" />
关闭左侧
</li>
<li v-if="!isLastView()" @click="closeRightTags">
<svg-icon icon-name="close_right" />
关闭右侧
</li>
<li @click="closeAllTags(selectedTag)">
<svg-icon icon-name="close_all" />
关闭所有
</li>
</ul>
</template>
<style lang="scss" scoped>
.tags-container {
height: 34px;
width: 100%;
border: 1px solid #eee;
box-shadow: 0px 1px 1px #eee;
.tags-item {
display: inline-block;
cursor: pointer;
@@ -324,7 +326,7 @@ onMounted(() => {
&.active {
background-color: var(--el-color-primary);
color: var(--el-color-primary-light-9);
color: #fff;
border-color: var(--el-color-primary);
&::before {
content: '';
@@ -333,22 +335,13 @@ onMounted(() => {
width: 8px;
height: 8px;
border-radius: 50%;
position: relative;
margin-right: 5px;
}
}
&-remove {
border-radius: 50%;
&:hover {
color: #fff;
background-color: #ccc;
}
}
}
}
.tags-item-menu {
.tag-menu {
background: #fff;
z-index: 99;
position: absolute;