79 changed files with 756 additions and 471 deletions
@ -1,2 +1,4 @@ |
|||
import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent'; |
|||
export const PageFooter = createAsyncComponent(() => import('./src/PageFooter.vue')); |
|||
|
|||
export { default as PageWrapper } from './src/PageWrapper.vue'; |
|||
|
|||
@ -0,0 +1,153 @@ |
|||
<template> |
|||
<div :class="getClass"> |
|||
<PageHeader :ghost="ghost" v-bind="$attrs" ref="headerRef"> |
|||
<template #default> |
|||
<template v-if="content"> |
|||
{{ content }} |
|||
</template> |
|||
<slot name="headerContent" v-else /> |
|||
</template> |
|||
<template #[item]="data" v-for="item in getHeaderSlots"> |
|||
<slot :name="item" v-bind="data" /> |
|||
</template> |
|||
</PageHeader> |
|||
<div :class="[`${prefixCls}-content`, $attrs.contentClass]" :style="getContentStyle"> |
|||
<slot /> |
|||
</div> |
|||
<PageFooter v-if="getShowFooter" ref="footerRef"> |
|||
<template #left> |
|||
<slot name="leftFooter" /> |
|||
</template> |
|||
<template #right> |
|||
<slot name="rightFooter" /> |
|||
</template> |
|||
</PageFooter> |
|||
</div> |
|||
</template> |
|||
<script lang="ts"> |
|||
import type { CSSProperties, PropType } from 'vue'; |
|||
|
|||
import { defineComponent, computed, watch, nextTick, ref, unref } from 'vue'; |
|||
import PageFooter from './PageFooter.vue'; |
|||
import { usePageContext } from '/@/hooks/component/usePageContext'; |
|||
|
|||
import { useDesign } from '/@/hooks/web/useDesign'; |
|||
import { propTypes } from '/@/utils/propTypes'; |
|||
import { omit } from 'lodash-es'; |
|||
import { PageHeader } from 'ant-design-vue'; |
|||
export default defineComponent({ |
|||
name: 'PageWrapper', |
|||
components: { PageFooter, PageHeader }, |
|||
props: { |
|||
dense: propTypes.bool, |
|||
ghost: propTypes.bool, |
|||
content: propTypes.string, |
|||
contentStyle: { |
|||
type: Object as PropType<CSSProperties>, |
|||
}, |
|||
contentBackgrond: propTypes.bool, |
|||
contentFullHeight: propTypes.bool, |
|||
}, |
|||
setup(props, { slots }) { |
|||
const headerRef = ref<ComponentRef>(null); |
|||
const footerRef = ref<ComponentRef>(null); |
|||
const { prefixCls } = useDesign('page-wrapper'); |
|||
const { contentHeight, setPageHeight, pageHeight } = usePageContext(); |
|||
|
|||
const getClass = computed(() => { |
|||
return [ |
|||
prefixCls, |
|||
{ |
|||
[`${prefixCls}--dense`]: props.dense, |
|||
}, |
|||
]; |
|||
}); |
|||
|
|||
const getShowFooter = computed(() => slots?.leftFooter || slots?.rightFooter); |
|||
|
|||
const getHeaderSlots = computed(() => { |
|||
return Object.keys(omit(slots, 'default', 'leftFooter', 'rightFooter', 'headerContent')); |
|||
}); |
|||
|
|||
const getContentStyle = computed( |
|||
(): CSSProperties => { |
|||
const { contentBackgrond, contentFullHeight, contentStyle } = props; |
|||
const bg = contentBackgrond ? { backgroundColor: '#fff' } : {}; |
|||
if (!contentFullHeight) { |
|||
return { ...bg, ...contentStyle }; |
|||
} |
|||
return { |
|||
...bg, |
|||
...contentStyle, |
|||
minHeight: `${unref(pageHeight)}px`, |
|||
}; |
|||
} |
|||
); |
|||
|
|||
watch( |
|||
() => contentHeight?.value, |
|||
(height) => { |
|||
if (!props.contentFullHeight) { |
|||
return; |
|||
} |
|||
nextTick(() => { |
|||
const footer = unref(footerRef); |
|||
const header = unref(headerRef); |
|||
let footetHeight = 0; |
|||
const footerEl = footer?.$el; |
|||
if (footerEl) { |
|||
footetHeight += footerEl?.offsetHeight ?? 0; |
|||
} |
|||
let headerHeight = 0; |
|||
const headerEl = header?.$el; |
|||
if (headerEl) { |
|||
headerHeight += headerEl?.offsetHeight ?? 0; |
|||
} |
|||
setPageHeight?.(height - footetHeight - headerHeight); |
|||
}); |
|||
}, |
|||
{ |
|||
immediate: true, |
|||
} |
|||
); |
|||
|
|||
return { |
|||
getContentStyle, |
|||
footerRef, |
|||
headerRef, |
|||
getClass, |
|||
getHeaderSlots, |
|||
prefixCls, |
|||
getShowFooter, |
|||
pageHeight, |
|||
omit, |
|||
}; |
|||
}, |
|||
}); |
|||
</script> |
|||
<style lang="less"> |
|||
@prefix-cls: ~'@{namespace}-page-wrapper'; |
|||
|
|||
.@{prefix-cls} { |
|||
position: relative; |
|||
|
|||
.ant-page-header { |
|||
padding: 12px 16px; |
|||
|
|||
&:empty { |
|||
padding: 0; |
|||
} |
|||
} |
|||
|
|||
&-content { |
|||
// padding: 12px; |
|||
margin: 16px; |
|||
} |
|||
|
|||
&--dense { |
|||
.@{prefix-cls}-content { |
|||
margin: 0; |
|||
} |
|||
} |
|||
} |
|||
</style> |
|||
@ -1,2 +1,4 @@ |
|||
import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent'; |
|||
export const BasicUpload = createAsyncComponent(() => import('./src/BasicUpload.vue')); |
|||
// import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent';
|
|||
// export const BasicUpload = createAsyncComponent(() => import('./src/BasicUpload.vue'));
|
|||
|
|||
export { default as BasicUpload } from './src/BasicUpload.vue'; |
|||
|
|||
@ -0,0 +1,20 @@ |
|||
import type { InjectionKey, ComputedRef, Ref } from 'vue'; |
|||
import { createContext, useContext } from '/@/hooks/core/useContext'; |
|||
|
|||
import {} from 'vue'; |
|||
|
|||
export interface PageContextProps { |
|||
contentHeight: ComputedRef<number>; |
|||
pageHeight: Ref<number>; |
|||
setPageHeight: (height: number) => Promise<void>; |
|||
} |
|||
|
|||
const key: InjectionKey<PageContextProps> = Symbol(); |
|||
|
|||
export function createPageContext(context: PageContextProps) { |
|||
return createContext<PageContextProps>(context, key, { native: true }); |
|||
} |
|||
|
|||
export function usePageContext() { |
|||
return useContext<PageContextProps>(key); |
|||
} |
|||
@ -0,0 +1,19 @@ |
|||
import type { InjectionKey, ComputedRef } from 'vue'; |
|||
import { createContext, useContext } from '/@/hooks/core/useContext'; |
|||
|
|||
import {} from 'vue'; |
|||
|
|||
export interface ContentContextProps { |
|||
contentHeight: ComputedRef<number>; |
|||
setPageHeight: (height: number) => Promise<void>; |
|||
} |
|||
|
|||
const key: InjectionKey<ContentContextProps> = Symbol(); |
|||
|
|||
export function createContentContext(context: ContentContextProps) { |
|||
return createContext<ContentContextProps>(context, key, { native: true }); |
|||
} |
|||
|
|||
export function useContentContext() { |
|||
return useContext<ContentContextProps>(key); |
|||
} |
|||
@ -0,0 +1,30 @@ |
|||
import { ref, computed, unref } from 'vue'; |
|||
import { createPageContext } from '/@/hooks/component/usePageContext'; |
|||
import { useWindowSizeFn } from '/@/hooks/event/useWindowSizeFn'; |
|||
export const headerHeightRef = ref(0); |
|||
|
|||
export function useContentViewHeight() { |
|||
const contentHeight = ref(window.innerHeight); |
|||
const pageHeight = ref(window.innerHeight); |
|||
const getViewHeight = computed(() => { |
|||
return unref(contentHeight) - unref(headerHeightRef) || 0; |
|||
}); |
|||
|
|||
useWindowSizeFn( |
|||
() => { |
|||
contentHeight.value = window.innerHeight; |
|||
}, |
|||
100, |
|||
{ immediate: true } |
|||
); |
|||
|
|||
async function setPageHeight(height: number) { |
|||
pageHeight.value = height; |
|||
} |
|||
|
|||
createPageContext({ |
|||
contentHeight: getViewHeight, |
|||
setPageHeight, |
|||
pageHeight, |
|||
}); |
|||
} |
|||
@ -1,10 +1,13 @@ |
|||
<template> |
|||
<div class="p-5"> |
|||
<PageWrapper title="层级面包屑示例" content="子级页面面包屑会添加到当前层级后面"> |
|||
<router-link to="/feat/breadcrumb/children/childrenDetail">进入子级详情页</router-link> |
|||
</div> |
|||
</PageWrapper> |
|||
</template> |
|||
<script lang="ts"> |
|||
import { defineComponent } from 'vue'; |
|||
import { PageWrapper } from '/@/components/Page'; |
|||
|
|||
export default defineComponent({}); |
|||
export default defineComponent({ |
|||
components: { PageWrapper }, |
|||
}); |
|||
</script> |
|||
|
|||
@ -1,10 +1,13 @@ |
|||
<template> |
|||
<div class="p-5"> |
|||
<PageWrapper title="平级面包屑示例" content="子级页面面包屑会覆盖当前层级"> |
|||
<router-link to="/feat/breadcrumb/flatDetail">进入平级详情页</router-link> |
|||
</div> |
|||
</PageWrapper> |
|||
</template> |
|||
<script lang="ts"> |
|||
import { defineComponent } from 'vue'; |
|||
import { PageWrapper } from '/@/components/Page'; |
|||
|
|||
export default defineComponent({}); |
|||
export default defineComponent({ |
|||
components: { PageWrapper }, |
|||
}); |
|||
</script> |
|||
|
|||
Loading…
Reference in new issue