feat: 布局问题

master
LCJ-MinYa 12 months ago
parent 1af036dfad
commit 5d0d614637

@ -0,0 +1,25 @@
<template>
<section class="base-container">
<slot></slot>
</section>
</template>
<script setup>
// import { computed } from 'vue';
// import { useGlobal } from '@pureadmin/utils';
// const { $storage } = useGlobal();
// const hideTabs = computed(() => {
// return $storage?.configure.hideTabs;
// });
</script>
<style lang="scss">
.base-container {
overflow: auto;
display: flex;
flex: 1;
flex-direction: column;
height: calc(100vh - 81px);
}
</style>

@ -0,0 +1,5 @@
<template>
<section class="base-container">
<slot></slot>
</section>
</template>

@ -0,0 +1,5 @@
<template>
<section class="base-container">
<slot></slot>
</section>
</template>

@ -0,0 +1,15 @@
<template>
<main class="base-main">
<slot></slot>
</main>
</template>
<style lang="scss">
.base-main {
display: flex;
flex-direction: column;
flex: 1;
overflow: auto;
height: calc(100vh - 81px);
}
</style>

@ -0,0 +1,14 @@
import { App, Component } from 'vue';
import BaseContainer from '@/components/AutoImport/BaseContainer/index.vue';
import BaseMain from '@/components/AutoImport/BaseMain/index.vue';
import BaseHeader from '@/components/AutoImport/BaseHeader/index.vue';
import BaseFooter from '@/components/AutoImport/BaseFooter/index.vue';
/** 注入全局组件 */
export function useAutoImport(app: App) {
// 全局注册组件
app.component('BaseContainer', BaseContainer);
app.component('BaseMain', BaseMain);
app.component('BaseHeader', BaseHeader);
app.component('BaseFooter', BaseFooter);
}

@ -1,213 +1,193 @@
<script setup lang="ts">
import LayFrame from "../lay-frame/index.vue";
import LayFooter from "../lay-footer/index.vue";
import { useTags } from "@/layout/hooks/useTag";
import { useGlobal, isNumber } from "@pureadmin/utils";
import BackTopIcon from "@/assets/svg/back_top.svg?component";
import { h, computed, Transition, defineComponent } from "vue";
import { usePermissionStoreHook } from "@/store/modules/permission";
import LayFrame from '../lay-frame/index.vue';
import LayFooter from '../lay-footer/index.vue';
import { useTags } from '@/layout/hooks/useTag';
import { useGlobal, isNumber } from '@pureadmin/utils';
import BackTopIcon from '@/assets/svg/back_top.svg?component';
import { h, computed, Transition, defineComponent } from 'vue';
import { usePermissionStoreHook } from '@/store/modules/permission';
const props = defineProps({
fixedHeader: Boolean
fixedHeader: Boolean,
});
const { showModel } = useTags();
const { $storage, $config } = useGlobal<GlobalPropertiesApi>();
const isKeepAlive = computed(() => {
return $config?.KeepAlive;
return $config?.KeepAlive;
});
const transitions = computed(() => {
return route => {
return route.meta.transition;
};
return (route) => {
return route.meta.transition;
};
});
const hideTabs = computed(() => {
return $storage?.configure.hideTabs;
return $storage?.configure.hideTabs;
});
const hideFooter = computed(() => {
return $storage?.configure.hideFooter;
return $storage?.configure.hideFooter;
});
const stretch = computed(() => {
return $storage?.configure.stretch;
return $storage?.configure.stretch;
});
const layout = computed(() => {
return $storage?.layout.layout === "vertical";
return $storage?.layout.layout === 'vertical';
});
const getMainWidth = computed(() => {
return isNumber(stretch.value)
? stretch.value + "px"
: stretch.value
? "1440px"
: "100%";
return isNumber(stretch.value) ? stretch.value + 'px' : stretch.value ? '1440px' : '100%';
});
const getSectionStyle = computed(() => {
return [
hideTabs.value && layout ? "padding-top: 48px;" : "",
!hideTabs.value && layout
? showModel.value == "chrome"
? "padding-top: 85px;"
: "padding-top: 81px;"
: "",
hideTabs.value && !layout.value ? "padding-top: 48px;" : "",
!hideTabs.value && !layout.value
? showModel.value == "chrome"
? "padding-top: 85px;"
: "padding-top: 81px;"
: "",
props.fixedHeader
? ""
: `padding-top: 0;${
hideTabs.value
? "min-height: calc(100vh - 48px);"
: "min-height: calc(100vh - 86px);"
}`
];
return [
hideTabs.value && layout ? 'padding-top: 48px;' : '',
!hideTabs.value && layout ? (showModel.value == 'chrome' ? 'padding-top: 85px;' : 'padding-top: 81px;') : '',
hideTabs.value && !layout.value ? 'padding-top: 48px;' : '',
!hideTabs.value && !layout.value ? (showModel.value == 'chrome' ? 'padding-top: 85px;' : 'padding-top: 81px;') : '',
props.fixedHeader ? '' : `padding-top: 0;${hideTabs.value ? 'min-height: calc(100vh - 48px);' : 'min-height: calc(100vh - 86px);'}`,
];
});
const transitionMain = defineComponent({
props: {
route: {
type: undefined,
required: true
}
},
render() {
const transitionName =
transitions.value(this.route)?.name || "fade-transform";
const enterTransition = transitions.value(this.route)?.enterTransition;
const leaveTransition = transitions.value(this.route)?.leaveTransition;
return h(
Transition,
{
name: enterTransition ? "pure-classes-transition" : transitionName,
enterActiveClass: enterTransition
? `animate__animated ${enterTransition}`
: undefined,
leaveActiveClass: leaveTransition
? `animate__animated ${leaveTransition}`
: undefined,
mode: "out-in",
appear: true
},
{
default: () => [this.$slots.default()]
}
);
}
props: {
route: {
type: undefined,
required: true,
},
},
render() {
const transitionName = transitions.value(this.route)?.name || 'fade-transform';
const enterTransition = transitions.value(this.route)?.enterTransition;
const leaveTransition = transitions.value(this.route)?.leaveTransition;
return h(
Transition,
{
name: enterTransition ? 'pure-classes-transition' : transitionName,
enterActiveClass: enterTransition ? `animate__animated ${enterTransition}` : undefined,
leaveActiveClass: leaveTransition ? `animate__animated ${leaveTransition}` : undefined,
mode: 'out-in',
appear: true,
},
{
default: () => [this.$slots.default()],
}
);
},
});
</script>
<template>
<section
:class="[fixedHeader ? 'app-main' : 'app-main-nofixed-header']"
:style="getSectionStyle"
>
<router-view>
<template #default="{ Component, route }">
<LayFrame :currComp="Component" :currRoute="route">
<template #default="{ Comp, fullPath, frameInfo }">
<el-scrollbar
v-if="fixedHeader"
:wrap-style="{
display: 'flex',
'flex-wrap': 'wrap',
'max-width': getMainWidth,
margin: '0 auto',
transition: 'all 300ms cubic-bezier(0.4, 0, 0.2, 1)'
}"
:view-style="{
display: 'flex',
flex: 'auto',
overflow: 'hidden',
'flex-direction': 'column'
}"
>
<el-backtop
title="回到顶部"
target=".app-main .el-scrollbar__wrap"
>
<BackTopIcon />
</el-backtop>
<div class="grow">
<transitionMain :route="route">
<keep-alive
v-if="isKeepAlive"
:include="usePermissionStoreHook().cachePageList"
>
<component
:is="Comp"
:key="fullPath"
:frameInfo="frameInfo"
class="main-content"
/>
</keep-alive>
<component
:is="Comp"
v-else
:key="fullPath"
:frameInfo="frameInfo"
class="main-content"
/>
</transitionMain>
</div>
<LayFooter v-if="!hideFooter" />
</el-scrollbar>
<div v-else class="grow">
<transitionMain :route="route">
<keep-alive
v-if="isKeepAlive"
:include="usePermissionStoreHook().cachePageList"
<section
:class="[fixedHeader ? 'app-main' : 'app-main-nofixed-header']"
:style="getSectionStyle"
>
<router-view>
<template #default="{ Component, route }">
<LayFrame
:currComp="Component"
:currRoute="route"
>
<component
:is="Comp"
:key="fullPath"
:frameInfo="frameInfo"
class="main-content"
/>
</keep-alive>
<component
:is="Comp"
v-else
:key="fullPath"
:frameInfo="frameInfo"
class="main-content"
/>
</transitionMain>
</div>
</template>
</LayFrame>
</template>
</router-view>
<!-- 页脚 -->
<LayFooter v-if="!hideFooter && !fixedHeader" />
</section>
<template #default="{ Comp, fullPath, frameInfo }">
<el-scrollbar
v-if="fixedHeader"
:wrap-style="{
display: 'flex',
'flex-wrap': 'wrap',
'max-width': getMainWidth,
margin: '0 auto',
transition: 'all 300ms cubic-bezier(0.4, 0, 0.2, 1)',
}"
:view-style="{
display: 'flex',
flex: 'auto',
overflow: 'hidden',
'flex-direction': 'column',
}"
>
<el-backtop
title="回到顶部"
target=".app-main .el-scrollbar__wrap"
>
<BackTopIcon />
</el-backtop>
<transitionMain :route="route">
<keep-alive
v-if="isKeepAlive"
:include="usePermissionStoreHook().cachePageList"
>
<component
:is="Comp"
:key="fullPath"
:frameInfo="frameInfo"
class="main-content"
/>
</keep-alive>
<component
:is="Comp"
v-else
:key="fullPath"
:frameInfo="frameInfo"
class="main-content"
/>
</transitionMain>
<LayFooter v-if="!hideFooter" />
</el-scrollbar>
<template v-else>
<transitionMain :route="route">
<keep-alive
v-if="isKeepAlive"
:include="usePermissionStoreHook().cachePageList"
>
<component
:is="Comp"
:key="fullPath"
:frameInfo="frameInfo"
class="main-content"
/>
</keep-alive>
<component
:is="Comp"
v-else
:key="fullPath"
:frameInfo="frameInfo"
class="main-content"
/>
</transitionMain>
</template>
</template>
</LayFrame>
</template>
</router-view>
<!-- 页脚 -->
<LayFooter v-if="!hideFooter && !fixedHeader" />
</section>
</template>
<style scoped>
.app-main {
position: relative;
width: 100%;
height: 100vh;
overflow-x: hidden;
position: relative;
width: 100%;
height: 100vh;
overflow-x: hidden;
}
.app-main-nofixed-header {
position: relative;
display: flex;
flex-direction: column;
width: 100%;
position: relative;
display: flex;
flex-direction: column;
width: 100%;
}
.main-content {
margin: 24px;
margin: 0;
}
</style>

@ -1,64 +1,61 @@
import App from "./App.vue";
import router from "./router";
import { setupStore } from "@/store";
import { getPlatformConfig } from "./config";
import { MotionPlugin } from "@vueuse/motion";
import App from './App.vue';
import router from './router';
import { setupStore } from '@/store';
import { getPlatformConfig } from './config';
import { MotionPlugin } from '@vueuse/motion';
// import { useEcharts } from "@/plugins/echarts";
import { createApp, type Directive } from "vue";
import { useElementPlus } from "@/plugins/elementPlus";
import { injectResponsiveStorage } from "@/utils/responsive";
import { createApp, type Directive } from 'vue';
import { useElementPlus } from '@/plugins/elementPlus';
import { injectResponsiveStorage } from '@/utils/responsive';
import { useAutoImport } from '@/components/AutoImport';
import Table from "@pureadmin/table";
import Table from '@pureadmin/table';
// import PureDescriptions from "@pureadmin/descriptions";
// 引入重置样式
import "./style/reset.scss";
import './style/reset.scss';
// 导入公共样式
import "./style/index.scss";
import './style/index.scss';
// 一定要在main.ts中导入tailwind.css防止vite每次hmr都会请求src/style/index.scss整体css文件导致热更新慢的问题
import "./style/tailwind.css";
import "element-plus/dist/index.css";
import './style/tailwind.css';
import 'element-plus/dist/index.css';
// 导入字体图标
import "./assets/iconfont/iconfont.js";
import "./assets/iconfont/iconfont.css";
import './assets/iconfont/iconfont.js';
import './assets/iconfont/iconfont.css';
const app = createApp(App);
// 自定义指令
import * as directives from "@/directives";
Object.keys(directives).forEach(key => {
app.directive(key, (directives as { [key: string]: Directive })[key]);
import * as directives from '@/directives';
Object.keys(directives).forEach((key) => {
app.directive(key, (directives as { [key: string]: Directive })[key]);
});
// 全局注册@iconify/vue图标库
import {
IconifyIconOffline,
IconifyIconOnline,
FontIcon
} from "./components/ReIcon";
app.component("IconifyIconOffline", IconifyIconOffline);
app.component("IconifyIconOnline", IconifyIconOnline);
app.component("FontIcon", FontIcon);
import { IconifyIconOffline, IconifyIconOnline, FontIcon } from './components/ReIcon';
app.component('IconifyIconOffline', IconifyIconOffline);
app.component('IconifyIconOnline', IconifyIconOnline);
app.component('FontIcon', FontIcon);
// 全局注册按钮级别权限组件
import { Auth } from "@/components/ReAuth";
import { Perms } from "@/components/RePerms";
app.component("Auth", Auth);
app.component("Perms", Perms);
import { Auth } from '@/components/ReAuth';
import { Perms } from '@/components/RePerms';
app.component('Auth', Auth);
app.component('Perms', Perms);
// 全局注册vue-tippy
import "tippy.js/dist/tippy.css";
import "tippy.js/themes/light.css";
import VueTippy from "vue-tippy";
import 'tippy.js/dist/tippy.css';
import 'tippy.js/themes/light.css';
import VueTippy from 'vue-tippy';
app.use(VueTippy);
getPlatformConfig(app).then(async config => {
setupStore(app);
app.use(router);
await router.isReady();
injectResponsiveStorage(app, config);
app.use(MotionPlugin).use(useElementPlus).use(Table);
// .use(PureDescriptions)
// .use(useEcharts);
app.mount("#app");
getPlatformConfig(app).then(async (config) => {
setupStore(app);
app.use(router);
await router.isReady();
injectResponsiveStorage(app, config);
app.use(MotionPlugin).use(useElementPlus).use(useAutoImport).use(Table);
// .use(PureDescriptions)
// .use(useEcharts);
app.mount('#app');
});

@ -1,248 +1,245 @@
// 按需引入element-plus该方法稳定且明确。当然也支持https://element-plus.org/zh-CN/guide/quickstart.html#%E6%8C%89%E9%9C%80%E5%AF%BC%E5%85%A5
import type { App, Component } from "vue";
import type { App, Component } from 'vue';
import {
/**
* 便 element-plus 使
* https://github.com/element-plus/element-plus/blob/dev/packages/element-plus/component.ts#L111-L211
* */
ElAffix,
ElAlert,
ElAutocomplete,
ElAutoResizer,
ElAvatar,
ElAnchor,
ElAnchorLink,
ElBacktop,
ElBadge,
ElBreadcrumb,
ElBreadcrumbItem,
ElButton,
ElButtonGroup,
ElCalendar,
ElCard,
ElCarousel,
ElCarouselItem,
ElCascader,
ElCascaderPanel,
ElCheckTag,
ElCheckbox,
ElCheckboxButton,
ElCheckboxGroup,
ElCol,
ElCollapse,
ElCollapseItem,
ElCollapseTransition,
ElColorPicker,
ElConfigProvider,
ElContainer,
ElAside,
ElFooter,
ElHeader,
ElMain,
ElDatePicker,
ElDescriptions,
ElDescriptionsItem,
ElDialog,
ElDivider,
ElDrawer,
ElDropdown,
ElDropdownItem,
ElDropdownMenu,
ElEmpty,
ElForm,
ElFormItem,
ElIcon,
ElImage,
ElImageViewer,
ElInput,
ElInputNumber,
ElLink,
ElMenu,
ElMenuItem,
ElMenuItemGroup,
ElSubMenu,
ElPageHeader,
ElPagination,
ElPopconfirm,
ElPopover,
ElPopper,
ElProgress,
ElRadio,
ElRadioButton,
ElRadioGroup,
ElRate,
ElResult,
ElRow,
ElScrollbar,
ElSelect,
ElOption,
ElOptionGroup,
ElSelectV2,
ElSkeleton,
ElSkeletonItem,
ElSlider,
ElSpace,
ElStatistic,
ElCountdown,
ElSteps,
ElStep,
ElSwitch,
ElTable,
ElTableColumn,
ElTableV2,
ElTabs,
ElTabPane,
ElTag,
ElText,
ElTimePicker,
ElTimeSelect,
ElTimeline,
ElTimelineItem,
ElTooltip,
ElTransfer,
ElTree,
ElTreeSelect,
ElTreeV2,
ElUpload,
ElWatermark,
ElTour,
ElTourStep,
ElSegmented,
/**
* 便 element-plus 使
* https://github.com/element-plus/element-plus/blob/dev/packages/element-plus/plugin.ts#L11-L16
* */
ElLoading, // v-loading 指令
ElInfiniteScroll, // v-infinite-scroll 指令
ElPopoverDirective, // v-popover 指令
ElMessage, // $message 全局属性对象globalProperties
ElMessageBox, // $msgbox、$alert、$confirm、$prompt 全局属性对象globalProperties
ElNotification // $notify 全局属性对象globalProperties
} from "element-plus";
/**
* 便 element-plus 使
* https://github.com/element-plus/element-plus/blob/dev/packages/element-plus/component.ts#L111-L211
* */
ElAffix,
ElAlert,
ElAutocomplete,
ElAutoResizer,
ElAvatar,
ElAnchor,
ElAnchorLink,
ElBacktop,
ElBadge,
ElBreadcrumb,
ElBreadcrumbItem,
ElButton,
ElButtonGroup,
ElCalendar,
ElCard,
ElCarousel,
ElCarouselItem,
ElCascader,
ElCascaderPanel,
ElCheckTag,
ElCheckbox,
ElCheckboxButton,
ElCheckboxGroup,
ElCol,
ElCollapse,
ElCollapseItem,
ElCollapseTransition,
ElColorPicker,
ElConfigProvider,
ElContainer,
ElAside,
ElFooter,
ElHeader,
ElMain,
ElDatePicker,
ElDescriptions,
ElDescriptionsItem,
ElDialog,
ElDivider,
ElDrawer,
ElDropdown,
ElDropdownItem,
ElDropdownMenu,
ElEmpty,
ElForm,
ElFormItem,
ElIcon,
ElImage,
ElImageViewer,
ElInput,
ElInputNumber,
ElLink,
ElMenu,
ElMenuItem,
ElMenuItemGroup,
ElSubMenu,
ElPageHeader,
ElPagination,
ElPopconfirm,
ElPopover,
ElPopper,
ElProgress,
ElRadio,
ElRadioButton,
ElRadioGroup,
ElRate,
ElResult,
ElRow,
ElScrollbar,
ElSelect,
ElOption,
ElOptionGroup,
ElSelectV2,
ElSkeleton,
ElSkeletonItem,
ElSlider,
ElSpace,
ElStatistic,
ElCountdown,
ElSteps,
ElStep,
ElSwitch,
ElTable,
ElTableColumn,
ElTableV2,
ElTabs,
ElTabPane,
ElTag,
ElText,
ElTimePicker,
ElTimeSelect,
ElTimeline,
ElTimelineItem,
ElTooltip,
ElTransfer,
ElTree,
ElTreeSelect,
ElTreeV2,
ElUpload,
ElWatermark,
ElTour,
ElTourStep,
ElSegmented,
/**
* 便 element-plus 使
* https://github.com/element-plus/element-plus/blob/dev/packages/element-plus/plugin.ts#L11-L16
* */
ElLoading, // v-loading 指令
ElInfiniteScroll, // v-infinite-scroll 指令
ElPopoverDirective, // v-popover 指令
ElMessage, // $message 全局属性对象globalProperties
ElMessageBox, // $msgbox、$alert、$confirm、$prompt 全局属性对象globalProperties
ElNotification, // $notify 全局属性对象globalProperties
} from 'element-plus';
const components = [
ElAffix,
ElAlert,
ElAutocomplete,
ElAutoResizer,
ElAvatar,
ElAnchor,
ElAnchorLink,
ElBacktop,
ElBadge,
ElBreadcrumb,
ElBreadcrumbItem,
ElButton,
ElButtonGroup,
ElCalendar,
ElCard,
ElCarousel,
ElCarouselItem,
ElCascader,
ElCascaderPanel,
ElCheckTag,
ElCheckbox,
ElCheckboxButton,
ElCheckboxGroup,
ElCol,
ElCollapse,
ElCollapseItem,
ElCollapseTransition,
ElColorPicker,
ElConfigProvider,
ElContainer,
ElAside,
ElFooter,
ElHeader,
ElMain,
ElDatePicker,
ElDescriptions,
ElDescriptionsItem,
ElDialog,
ElDivider,
ElDrawer,
ElDropdown,
ElDropdownItem,
ElDropdownMenu,
ElEmpty,
ElForm,
ElFormItem,
ElIcon,
ElImage,
ElImageViewer,
ElInput,
ElInputNumber,
ElLink,
ElMenu,
ElMenuItem,
ElMenuItemGroup,
ElSubMenu,
ElPageHeader,
ElPagination,
ElPopconfirm,
ElPopover,
ElPopper,
ElProgress,
ElRadio,
ElRadioButton,
ElRadioGroup,
ElRate,
ElResult,
ElRow,
ElScrollbar,
ElSelect,
ElOption,
ElOptionGroup,
ElSelectV2,
ElSkeleton,
ElSkeletonItem,
ElSlider,
ElSpace,
ElStatistic,
ElCountdown,
ElSteps,
ElStep,
ElSwitch,
ElTable,
ElTableColumn,
ElTableV2,
ElTabs,
ElTabPane,
ElTag,
ElText,
ElTimePicker,
ElTimeSelect,
ElTimeline,
ElTimelineItem,
ElTooltip,
ElTransfer,
ElTree,
ElTreeSelect,
ElTreeV2,
ElUpload,
ElWatermark,
ElTour,
ElTourStep,
ElSegmented
ElAffix,
ElAlert,
ElAutocomplete,
ElAutoResizer,
ElAvatar,
ElAnchor,
ElAnchorLink,
ElBacktop,
ElBadge,
ElBreadcrumb,
ElBreadcrumbItem,
ElButton,
ElButtonGroup,
ElCalendar,
ElCard,
ElCarousel,
ElCarouselItem,
ElCascader,
ElCascaderPanel,
ElCheckTag,
ElCheckbox,
ElCheckboxButton,
ElCheckboxGroup,
ElCol,
ElCollapse,
ElCollapseItem,
ElCollapseTransition,
ElColorPicker,
ElConfigProvider,
ElContainer,
ElAside,
ElFooter,
ElHeader,
ElMain,
ElDatePicker,
ElDescriptions,
ElDescriptionsItem,
ElDialog,
ElDivider,
ElDrawer,
ElDropdown,
ElDropdownItem,
ElDropdownMenu,
ElEmpty,
ElForm,
ElFormItem,
ElIcon,
ElImage,
ElImageViewer,
ElInput,
ElInputNumber,
ElLink,
ElMenu,
ElMenuItem,
ElMenuItemGroup,
ElSubMenu,
ElPageHeader,
ElPagination,
ElPopconfirm,
ElPopover,
ElPopper,
ElProgress,
ElRadio,
ElRadioButton,
ElRadioGroup,
ElRate,
ElResult,
ElRow,
ElScrollbar,
ElSelect,
ElOption,
ElOptionGroup,
ElSelectV2,
ElSkeleton,
ElSkeletonItem,
ElSlider,
ElSpace,
ElStatistic,
ElCountdown,
ElSteps,
ElStep,
ElSwitch,
ElTable,
ElTableColumn,
ElTableV2,
ElTabs,
ElTabPane,
ElTag,
ElText,
ElTimePicker,
ElTimeSelect,
ElTimeline,
ElTimelineItem,
ElTooltip,
ElTransfer,
ElTree,
ElTreeSelect,
ElTreeV2,
ElUpload,
ElWatermark,
ElTour,
ElTourStep,
ElSegmented,
];
const plugins = [
ElLoading,
ElInfiniteScroll,
ElPopoverDirective,
ElMessage,
ElMessageBox,
ElNotification
];
const plugins = [ElLoading, ElInfiniteScroll, ElPopoverDirective, ElMessage, ElMessageBox, ElNotification];
/** 设置部分组件的默认属性 */
ElCard.props.shadow = { type: String, default: 'never' };
ElButton.props.round = { type: Boolean, default: true };
/** 按需引入`element-plus` */
export function useElementPlus(app: App) {
// 全局注册组件
components.forEach((component: Component) => {
app.component(component.name, component);
});
// 全局注册插件
plugins.forEach(plugin => {
app.use(plugin);
});
// 全局注册组件
components.forEach((component: Component) => {
app.component(component.name, component);
});
// 全局注册插件
plugins.forEach((plugin) => {
app.use(plugin);
});
}

@ -19,5 +19,13 @@ export default {
title: '基础模版',
},
},
{
path: '/template/layout',
name: 'TemplateLayout',
component: () => import('@/views/template/layout/index.vue'),
meta: {
title: '布局模版',
},
},
],
} satisfies RouteConfigsTable;

@ -1,188 +1,193 @@
.el-form-item__label {
font-weight: 700;
font-weight: 700;
}
.el-breadcrumb__inner,
.el-breadcrumb__inner a {
font-weight: 400 !important;
font-weight: 400 !important;
}
.el-dropdown-menu {
padding: 0 !important;
padding: 0 !important;
}
.is-dark {
z-index: 9999 !important;
z-index: 9999 !important;
}
/* 重置 el-button 中 icon 的 margin */
.reset-margin [class*="el-icon"] + span {
margin-left: 2px !important;
.reset-margin [class*='el-icon'] + span {
margin-left: 2px !important;
}
/* 自定义 popover 的类名 */
.pure-popper {
padding: 0 !important;
padding: 0 !important;
}
/* nprogress 适配 element-plus 的主题色 */
#nprogress {
& .bar {
background-color: var(--el-color-primary) !important;
}
& .bar {
background-color: var(--el-color-primary) !important;
}
& .peg {
box-shadow:
0 0 10px var(--el-color-primary),
0 0 5px var(--el-color-primary) !important;
}
& .spinner-icon {
border-top-color: var(--el-color-primary);
border-left-color: var(--el-color-primary);
}
& .peg {
box-shadow:
0 0 10px var(--el-color-primary),
0 0 5px var(--el-color-primary) !important;
}
& .spinner-icon {
border-top-color: var(--el-color-primary);
border-left-color: var(--el-color-primary);
}
}
.pure-dialog {
.el-dialog__header.show-close {
padding-right: 16px;
}
.el-dialog__headerbtn {
top: 16px;
right: 12px;
width: 24px;
height: 24px;
}
.pure-dialog-svg {
color: var(--el-color-info);
}
.el-dialog__footer {
padding-top: 0;
}
.el-dialog__header.show-close {
padding-right: 16px;
}
.el-dialog__headerbtn {
top: 16px;
right: 12px;
width: 24px;
height: 24px;
}
.pure-dialog-svg {
color: var(--el-color-info);
}
.el-dialog__footer {
padding-top: 0;
}
}
/* 全局覆盖element-plus的el-tour、el-dialog、el-drawer、el-message-box、el-notification组件右上角关闭图标和el-upload上传文件列表右侧关闭图标的样式表现更鲜明 */
.el-dialog__headerbtn,
.el-message-box__headerbtn {
&:hover {
.el-dialog__close {
color: var(--el-color-info) !important;
&:hover {
.el-dialog__close {
color: var(--el-color-info) !important;
}
}
}
}
.el-icon {
&.el-tour__close,
&.el-dialog__close,
&.el-drawer__close,
&.el-message-box__close,
&.el-notification__closeBtn,
.el-upload-list__item.is-ready &.el-icon--close {
width: 24px;
height: 24px;
border-radius: 4px;
outline: none;
transition:
background-color 0.2s,
color 0.2s;
&:hover {
color: rgb(0 0 0 / 88%) !important;
text-decoration: none;
background-color: rgb(0 0 0 / 6%);
.pure-dialog-svg {
color: rgb(0 0 0 / 88%) !important;
}
&.el-tour__close,
&.el-dialog__close,
&.el-drawer__close,
&.el-message-box__close,
&.el-notification__closeBtn,
.el-upload-list__item.is-ready &.el-icon--close {
width: 24px;
height: 24px;
border-radius: 4px;
outline: none;
transition:
background-color 0.2s,
color 0.2s;
&:hover {
color: rgb(0 0 0 / 88%) !important;
text-decoration: none;
background-color: rgb(0 0 0 / 6%);
.pure-dialog-svg {
color: rgb(0 0 0 / 88%) !important;
}
}
}
}
}
/* 克隆并自定义 ElMessage 样式,不会影响 ElMessage 原本样式,在 src/utils/message.ts 中调用自定义样式 ElMessage 方法即可,整体暗色风格在 src/style/dark.scss 文件进行了适配 */
.pure-message {
background: #fff !important;
border-width: 0 !important;
box-shadow:
0 3px 6px -4px #0000001f,
0 6px 16px #00000014,
0 9px 28px 8px #0000000d !important;
& .el-message__content {
color: #000000d9 !important;
pointer-events: all !important;
background-image: initial !important;
}
& .el-message__closeBtn {
border-radius: 4px;
outline: none;
transition:
background-color 0.2s,
color 0.2s;
background: #fff !important;
border-width: 0 !important;
box-shadow:
0 3px 6px -4px #0000001f,
0 6px 16px #00000014,
0 9px 28px 8px #0000000d !important;
& .el-message__content {
color: #000000d9 !important;
pointer-events: all !important;
background-image: initial !important;
}
&:hover {
background-color: rgb(0 0 0 / 6%);
& .el-message__closeBtn {
border-radius: 4px;
outline: none;
transition:
background-color 0.2s,
color 0.2s;
&:hover {
background-color: rgb(0 0 0 / 6%);
}
}
}
}
/* 自定义菜单搜索样式 */
.pure-search-dialog {
@media screen and (width > 760px) and (width <= 940px) {
.el-input__inner {
font-size: 12px;
@media screen and (width > 760px) and (width <= 940px) {
.el-input__inner {
font-size: 12px;
}
}
}
@media screen and (width <= 470px) {
.el-input__inner {
font-size: 12px;
@media screen and (width <= 470px) {
.el-input__inner {
font-size: 12px;
}
}
}
.el-dialog__header {
display: none;
}
.el-dialog__header {
display: none;
}
.el-input__inner {
font-size: 1.2em;
}
.el-input__inner {
font-size: 1.2em;
}
.el-dialog__footer {
width: calc(100% + 32px);
padding: 10px 20px;
margin: auto -16px -16px;
box-shadow:
0 -1px 0 0 #e0e3e8,
0 -3px 6px 0 rgb(69 98 155 / 12%);
}
.el-dialog__footer {
width: calc(100% + 32px);
padding: 10px 20px;
margin: auto -16px -16px;
box-shadow:
0 -1px 0 0 #e0e3e8,
0 -3px 6px 0 rgb(69 98 155 / 12%);
}
}
/* 仿 el-scrollbar 滚动条样式支持大多数浏览器如Chrome、Edge、Firefox、Safari等。整体暗色风格在 src/style/dark.scss 文件进行了适配 */
.pure-scrollbar {
/* Firefox */
scrollbar-width: thin; /* 可选值为 'auto', 'thin', 'none' */
scrollbar-color: rgb(221 222 224) transparent; /* 滑块颜色、轨道颜色 */
::-webkit-scrollbar {
width: 6px; /* 滚动条宽度 */
}
/* 滚动条轨道 */
::-webkit-scrollbar-track {
background: transparent; /* 轨道颜色 */
}
/* 滚动条滑块 */
::-webkit-scrollbar-thumb {
background-color: rgb(221 222 224);
border-radius: 4px;
}
/* 滚动条滑块hover状态 */
::-webkit-scrollbar-thumb:hover {
background: rgb(199 201 203); /* 滑块hover颜色 */
}
/* Firefox */
scrollbar-width: thin; /* 可选值为 'auto', 'thin', 'none' */
scrollbar-color: rgb(221 222 224) transparent; /* 滑块颜色、轨道颜色 */
::-webkit-scrollbar {
width: 6px; /* 滚动条宽度 */
}
/* 滚动条轨道 */
::-webkit-scrollbar-track {
background: transparent; /* 轨道颜色 */
}
/* 滚动条滑块 */
::-webkit-scrollbar-thumb {
background-color: rgb(221 222 224);
border-radius: 4px;
}
/* 滚动条滑块hover状态 */
::-webkit-scrollbar-thumb:hover {
background: rgb(199 201 203); /* 滑块hover颜色 */
}
}
/** 默认el-card没有边框 */
.el-card {
border: none !important;
}

@ -0,0 +1,225 @@
<template>
<Base-Container>
<pure-table
class="base-main"
:data="tableData"
:columns="columns"
size="large"
/>
</Base-Container>
</template>
<script setup lang="jsx">
import { ref } from 'vue';
defineOptions({
name: 'TemplateLayout',
});
const tableData = ref([
{
name: 'John',
age: 25,
},
{
name: 'Jane',
age: 30,
},
{
name: 'Bob',
age: 28,
},
{
name: 'John',
age: 25,
},
{
name: 'Jane',
age: 30,
},
{
name: 'Bob',
age: 28,
},
{
name: 'John',
age: 25,
},
{
name: 'Jane',
age: 30,
},
{
name: 'Bob',
age: 28,
},
{
name: 'John',
age: 25,
},
{
name: 'Jane',
age: 30,
},
{
name: 'Bob',
age: 28,
},
{
name: 'John',
age: 25,
},
{
name: 'Jane',
age: 30,
},
{
name: 'Bob',
age: 28,
},
{
name: 'John',
age: 25,
},
{
name: 'Jane',
age: 30,
},
{
name: 'Bob',
age: 28,
},
{
name: 'John',
age: 25,
},
{
name: 'Jane',
age: 30,
},
{
name: 'Bob',
age: 28,
},
{
name: 'John',
age: 25,
},
{
name: 'Jane',
age: 30,
},
{
name: 'Bob',
age: 28,
},
{
name: 'John',
age: 25,
},
{
name: 'Jane',
age: 30,
},
{
name: 'Bob',
age: 28,
},
{
name: 'John',
age: 25,
},
{
name: 'Jane',
age: 30,
},
{
name: 'Bob',
age: 28,
},
{
name: 'John',
age: 25,
},
{
name: 'Jane',
age: 30,
},
{
name: 'Bob',
age: 28,
},
{
name: 'John',
age: 25,
},
{
name: 'Jane',
age: 30,
},
{
name: 'Bob',
age: 28,
},
{
name: 'John',
age: 25,
},
{
name: 'Jane',
age: 30,
},
{
name: 'Bob',
age: 28,
},
{
name: 'John',
age: 25,
},
{
name: 'Jane',
age: 30,
},
{
name: 'Bob',
age: 28,
},
{
name: 'John',
age: 25,
},
{
name: 'Jane',
age: 30,
},
{
name: 'Bob',
age: 28,
},
{
name: 'John',
age: 25,
},
{
name: 'Jane',
age: 30,
},
{
name: 'Bob',
age: 28,
},
]);
const columns = [
{
label: '姓名',
prop: 'name',
},
{
label: '年龄',
prop: 'age',
},
];
</script>
<style lang="scss" scoped></style>
Loading…
Cancel
Save