feat: add vue3(element-plus)

This commit is contained in:
xingyu
2022-07-18 19:06:37 +08:00
parent c6b58dca52
commit 80a3ae8d74
423 changed files with 41039 additions and 0 deletions

View File

@ -0,0 +1,78 @@
<script lang="tsx">
import { computed, defineComponent, unref } from 'vue'
import { useAppStore } from '@/store/modules/app'
import { Backtop } from '@/components/Backtop'
import { Setting } from '@/components/Setting'
import { useRenderLayout } from './components/useRenderLayout'
import { useDesign } from '@/hooks/web/useDesign'
const { getPrefixCls } = useDesign()
const prefixCls = getPrefixCls('layout')
const appStore = useAppStore()
// 是否是移动端
const mobile = computed(() => appStore.getMobile)
// 菜单折叠
const collapse = computed(() => appStore.getCollapse)
const layout = computed(() => appStore.getLayout)
const handleClickOutside = () => {
appStore.setCollapse(true)
}
const renderLayout = () => {
switch (unref(layout)) {
case 'classic':
const { renderClassic } = useRenderLayout()
return renderClassic()
case 'topLeft':
const { renderTopLeft } = useRenderLayout()
return renderTopLeft()
case 'top':
const { renderTop } = useRenderLayout()
return renderTop()
case 'cutMenu':
const { renderCutMenu } = useRenderLayout()
return renderCutMenu()
default:
break
}
}
export default defineComponent({
name: 'Layout',
setup() {
return () => (
<section class={[prefixCls, `${prefixCls}__${layout.value}`, 'w-[100%] h-[100%] relative']}>
{mobile.value && !collapse.value ? (
<div
class="absolute top-0 left-0 w-full h-full opacity-30 z-99 bg-[var(--el-color-black)]"
onClick={handleClickOutside}
></div>
) : undefined}
{renderLayout()}
<Backtop></Backtop>
<Setting></Setting>
</section>
)
}
})
</script>
<style lang="less" scoped>
@prefix-cls: ~'@{namespace}-layout';
.@{prefix-cls} {
background-color: var(--app-contnet-bg-color);
:deep(.@{elNamespace}-scrollbar__view) {
height: 100% !important;
}
}
</style>

View File

@ -0,0 +1,52 @@
<script setup lang="ts">
import { useTagsViewStore } from '@/store/modules/tagsView'
import { useAppStore } from '@/store/modules/app'
import { Footer } from '@/components/Footer'
import { computed } from 'vue'
const appStore = useAppStore()
const layout = computed(() => appStore.getLayout)
const fixedHeader = computed(() => appStore.getFixedHeader)
const footer = computed(() => appStore.getFooter)
const tagsViewStore = useTagsViewStore()
const getCaches = computed((): string[] => {
return tagsViewStore.getCachedViews
})
</script>
<template>
<section
:class="[
'p-[var(--app-content-padding)] w-[100%] bg-[var(--app-contnet-bg-color)] dark:bg-[var(--el-bg-color)]',
{
'!min-h-[calc(100%-var(--app-footer-height))]':
fixedHeader && (layout === 'classic' || layout === 'topLeft') && footer,
'!min-h-[calc(100%-var(--tags-view-height)-var(--top-tool-height)-var(--app-footer-height))]':
((!fixedHeader && layout === 'classic') || layout === 'top') && footer,
'!min-h-[calc(100%-var(--tags-view-height)-var(--app-footer-height))]':
!fixedHeader && layout === 'topLeft' && footer,
'!min-h-[calc(100%-var(--top-tool-height))]': fixedHeader && layout === 'cutMenu' && footer,
'!min-h-[calc(100%-var(--top-tool-height)-var(--tags-view-height))]':
!fixedHeader && layout === 'cutMenu' && footer
}
]"
>
<router-view>
<template #default="{ Component, route }">
<keep-alive :include="getCaches">
<component :is="Component" :key="route.fullPath" />
</keep-alive>
</template>
</router-view>
</section>
<Footer v-if="footer" />
</template>

View File

@ -0,0 +1,83 @@
<script lang="tsx">
import { defineComponent, computed } from 'vue'
import { Collapse } from '@/components/Collapse'
import { LocaleDropdown } from '@/components/LocaleDropdown'
import { SizeDropdown } from '@/components/SizeDropdown'
import { UserInfo } from '@/components/UserInfo'
import { Screenfull } from '@/components/Screenfull'
import { Breadcrumb } from '@/components/Breadcrumb'
import { useAppStore } from '@/store/modules/app'
import { useDesign } from '@/hooks/web/useDesign'
const { getPrefixCls, variables } = useDesign()
const prefixCls = getPrefixCls('tool-header')
const appStore = useAppStore()
// 面包屑
const breadcrumb = computed(() => appStore.getBreadcrumb)
// 折叠图标
const hamburger = computed(() => appStore.getHamburger)
// 全屏图标
const screenfull = computed(() => appStore.getScreenfull)
// 尺寸图标
const size = computed(() => appStore.getSize)
// 布局
const layout = computed(() => appStore.getLayout)
// 多语言图标
const locale = computed(() => appStore.getLocale)
export default defineComponent({
name: 'ToolHeader',
setup() {
return () => (
<div
id={`${variables.namespace}-tool-header`}
class={[
prefixCls,
'h-[var(--top-tool-height)] relative px-[var(--top-tool-p-x)] flex items-center justify-between',
'dark:bg-[var(--el-bg-color)]'
]}
>
{layout.value !== 'top' ? (
<div class="h-full flex items-center">
{hamburger.value && layout.value !== 'cutMenu' ? (
<Collapse class="hover-tigger" color="var(--top-header-text-color)"></Collapse>
) : undefined}
{breadcrumb.value ? <Breadcrumb class="<md:hidden"></Breadcrumb> : undefined}
</div>
) : undefined}
<div class="h-full flex items-center">
{screenfull.value ? (
<Screenfull class="hover-tigger" color="var(--top-header-text-color)"></Screenfull>
) : undefined}
{size.value ? (
<SizeDropdown class="hover-tigger" color="var(--top-header-text-color)"></SizeDropdown>
) : undefined}
{locale.value ? (
<LocaleDropdown
class="hover-tigger"
color="var(--top-header-text-color)"
></LocaleDropdown>
) : undefined}
<UserInfo class="hover-tigger"></UserInfo>
</div>
</div>
)
}
})
</script>
<style lang="less" scoped>
@prefix-cls: ~'@{namespace}-tool-header';
.@{prefix-cls} {
transition: left var(--transition-time-02);
}
</style>

View File

@ -0,0 +1,263 @@
import { computed } from 'vue'
import { useAppStore } from '@/store/modules/app'
import { Menu } from '@/components/Menu'
import { TabMenu } from '@/components/TabMenu'
import { TagsView } from '@/components/TagsView'
import { Logo } from '@/components/Logo'
import AppView from './AppView.vue'
import ToolHeader from './ToolHeader.vue'
import { ElScrollbar } from 'element-plus'
import { useDesign } from '@/hooks/web/useDesign'
const { getPrefixCls } = useDesign()
const prefixCls = getPrefixCls('layout')
const appStore = useAppStore()
const pageLoading = computed(() => appStore.getPageLoading)
// 标签页
const tagsView = computed(() => appStore.getTagsView)
// 菜单折叠
const collapse = computed(() => appStore.getCollapse)
// logo
const logo = computed(() => appStore.logo)
// 固定头部
const fixedHeader = computed(() => appStore.getFixedHeader)
// 是否是移动端
const mobile = computed(() => appStore.getMobile)
export const useRenderLayout = () => {
const renderClassic = () => {
return (
<>
<div class={['absolute top-0 left-0 h-full', { '!fixed z-3000': mobile.value }]}>
{logo.value ? (
<Logo
class={[
'bg-[var(--left-menu-bg-color)] border-bottom-1 border-solid border-[var(--logo-border-color)] dark:border-[var(--el-border-color)]',
{
'!pl-0': mobile.value && collapse.value,
'w-[var(--left-menu-min-width)]': appStore.getCollapse,
'w-[var(--left-menu-max-width)]': !appStore.getCollapse
}
]}
style="transition: all var(--transition-time-02);"
></Logo>
) : undefined}
<Menu class={[{ '!h-[calc(100%-var(--logo-height))]': logo.value }]}></Menu>
</div>
<div
class={[
`${prefixCls}-content`,
'absolute top-0 h-[100%]',
{
'w-[calc(100%-var(--left-menu-min-width))] left-[var(--left-menu-min-width)]':
collapse.value && !mobile.value && !mobile.value,
'w-[calc(100%-var(--left-menu-max-width))] left-[var(--left-menu-max-width)]':
!collapse.value && !mobile.value && !mobile.value,
'fixed !w-full !left-0': mobile.value
}
]}
style="transition: all var(--transition-time-02);"
>
<ElScrollbar
v-loading={pageLoading.value}
class={[
`${prefixCls}-content-scrollbar`,
{
'!h-[calc(100%-var(--top-tool-height)-var(--tags-view-height))] mt-[calc(var(--top-tool-height)+var(--tags-view-height))]':
fixedHeader.value
}
]}
>
<div
class={[
{
'fixed top-0 left-0 z-10': fixedHeader.value,
'w-[calc(100%-var(--left-menu-min-width))] left-[var(--left-menu-min-width)]':
collapse.value && fixedHeader.value && !mobile.value,
'w-[calc(100%-var(--left-menu-max-width))] left-[var(--left-menu-max-width)]':
!collapse.value && fixedHeader.value && !mobile.value,
'!w-full !left-0': mobile.value
}
]}
style="transition: all var(--transition-time-02);"
>
<ToolHeader class="border-bottom-1 border-solid border-[var(--top-tool-border-color)] bg-[var(--top-header-bg-color)] dark:border-[var(--el-border-color)]"></ToolHeader>
{tagsView.value ? (
<TagsView class="border-bottom-1 border-top-1 border-solid border-[var(--tags-view-border-color)] dark:border-[var(--el-border-color)]"></TagsView>
) : undefined}
</div>
<AppView></AppView>
</ElScrollbar>
</div>
</>
)
}
const renderTopLeft = () => {
return (
<>
<div class="flex items-center bg-[var(--top-header-bg-color)] border-bottom-1 border-solid border-[var(--top-tool-border-color)] dark:border-[var(--el-border-color)]">
{logo.value ? <Logo class="hover-tigger !pr-15px"></Logo> : undefined}
<ToolHeader class="flex-1"></ToolHeader>
</div>
<div class="absolute top-[var(--logo-height)+1px] left-0 w-full h-[calc(100%-1px-var(--logo-height))] flex">
<Menu class="!h-full"></Menu>
<div
class={[
`${prefixCls}-content`,
'h-[100%]',
{
'w-[calc(100%-var(--left-menu-min-width))] left-[var(--left-menu-min-width)]':
collapse.value,
'w-[calc(100%-var(--left-menu-max-width))] left-[var(--left-menu-max-width)]':
!collapse.value
}
]}
style="transition: all var(--transition-time-02);"
>
<ElScrollbar
v-loading={pageLoading.value}
class={[
`${prefixCls}-content-scrollbar`,
{
'!h-[calc(100%-var(--tags-view-height))] mt-[calc(var(--tags-view-height))]':
fixedHeader.value && tagsView.value
}
]}
>
{tagsView.value ? (
<TagsView
class={[
'border-bottom-1 border-top-1 border-solid border-[var(--tags-view-border-color)] dark:border-[var(--el-border-color)]',
{
'!fixed top-0 left-0 z-10': fixedHeader.value,
'w-[calc(100%-var(--left-menu-min-width))] left-[var(--left-menu-min-width)] mt-[var(--logo-height)]':
collapse.value && fixedHeader.value,
'w-[calc(100%-var(--left-menu-max-width))] left-[var(--left-menu-max-width)] mt-[var(--logo-height)]':
!collapse.value && fixedHeader.value
}
]}
style="transition: width var(--transition-time-02), left var(--transition-time-02);"
></TagsView>
) : undefined}
<AppView></AppView>
</ElScrollbar>
</div>
</div>
</>
)
}
const renderTop = () => {
return (
<>
<div class="flex items-center justify-between bg-[var(--top-header-bg-color)] border-bottom-1 border-solid border-[var(--top-tool-border-color)] dark:border-[var(--el-border-color)]">
{logo.value ? <Logo class="hover-tigger"></Logo> : undefined}
<Menu class="flex-1 px-10px h-[var(--top-tool-height)]"></Menu>
<ToolHeader></ToolHeader>
</div>
<div class={[`${prefixCls}-content`, 'h-full w-full']}>
<ElScrollbar
v-loading={pageLoading.value}
class={[
`${prefixCls}-content-scrollbar`,
{
'mt-[var(--tags-view-height)]': fixedHeader.value
}
]}
>
{tagsView.value ? (
<TagsView
class={[
'border-bottom-1 border-top-1 border-solid border-[var(--tags-view-border-color)] dark:border-[var(--el-border-color)]',
{
'!fixed w-full top-[var(--top-tool-height)] left-0': fixedHeader.value
}
]}
style="transition: width var(--transition-time-02), left var(--transition-time-02);"
></TagsView>
) : undefined}
<AppView></AppView>
</ElScrollbar>
</div>
</>
)
}
const renderCutMenu = () => {
return (
<>
<div class="flex items-center bg-[var(--top-header-bg-color)] border-bottom-1 border-solid border-[var(--top-tool-border-color)] dark:border-[var(--el-border-color)]">
{logo.value ? <Logo class="hover-tigger !pr-15px"></Logo> : undefined}
<ToolHeader class="flex-1"></ToolHeader>
</div>
<div class="absolute top-[var(--logo-height)] left-0 w-full h-[calc(100%-var(--logo-height))] flex">
<TabMenu></TabMenu>
<div
class={[
`${prefixCls}-content`,
'h-[100%]',
{
'w-[calc(100%-var(--tab-menu-min-width))] left-[var(--tab-menu-min-width)]':
collapse.value,
'w-[calc(100%-var(--tab-menu-max-width))] left-[var(--tab-menu-max-width)]':
!collapse.value
}
]}
style="transition: all var(--transition-time-02);"
>
<ElScrollbar
v-loading={pageLoading.value}
class={[
`${prefixCls}-content-scrollbar`,
{
'!h-[calc(100%-var(--tags-view-height))] mt-[calc(var(--tags-view-height))]':
fixedHeader.value && tagsView.value
}
]}
>
{tagsView.value ? (
<TagsView
class={[
'border-bottom-1 border-top-1 border-solid border-[var(--tags-view-border-color)] dark:border-[var(--el-border-color)]',
{
'!fixed top-0 left-0 z-10': fixedHeader.value,
'w-[calc(100%-var(--tab-menu-min-width))] left-[var(--tab-menu-min-width)] mt-[var(--logo-height)]':
collapse.value && fixedHeader.value,
'w-[calc(100%-var(--tab-menu-max-width))] left-[var(--tab-menu-max-width)] mt-[var(--logo-height)]':
!collapse.value && fixedHeader.value
}
]}
style="transition: width var(--transition-time-02), left var(--transition-time-02);"
></TagsView>
) : undefined}
<AppView></AppView>
</ElScrollbar>
</div>
</div>
</>
)
}
return {
renderClassic,
renderTopLeft,
renderTop,
renderCutMenu
}
}