Unverified Commit daad9bf8 authored by Sendya's avatar Sendya

feat: slots prop

parent 1b8e4e25
<template>
<pro-layout
title="Ant Design Pro"
:menus="menus"
:collapsed="collapsed"
:theme="theme"
:layout="layout"
:contentWidth="contentWidth"
:auto-hide-header="autoHideHeader"
:mediaQuery="query"
:isMobile="isMobile"
:handleMediaQuery="handleMediaQuery"
:handleCollapse="handleCollapse"
:logo="logoRender"
:i18nRender="i18nRender"
>
<template v-slot:rightContentRender>
<div :class="['ant-pro-global-header-index-right', layout === 'topmenu' && `ant-pro-global-header-index-${theme}`]">
rightContentRender
</div>
</template>
<template v-slot:footerRender>
<div>footerRender</div>
</template>
<router-view />
</pro-layout>
</template>
<script>
import ProLayout from '@ant-design-vue/pro-layout'
import { asyncRouterMap } from '../config/router.config'
import { i18nRender } from '../locales'
import LogoSvg from '../assets/logo.svg?inline'
export default {
name: 'BasicLayout',
data () {
return {
// base
menus: [],
// 侧栏收起状态
collapsed: false,
// 自动隐藏头部栏
autoHideHeader: false,
// 媒体查询
query: {},
// 布局类型
layout: 'sidemenu', // 'sidemenu', 'topmenu'
// 定宽: true / 流式: false
contentWidth: true,
// 主题 'dark' | 'light'
theme: 'dark',
// 是否手机模式
isMobile: false
}
},
created () {
this.menus = asyncRouterMap.find(item => item.path === '/').children
},
methods: {
i18nRender,
handleMediaQuery (val) {
this.query = val
if (this.isMobile && !val['screen-xs']) {
this.isMobile = false
return
}
if (!this.isMobile && val['screen-xs']) {
this.isMobile = true
this.collapsed = false
}
},
handleCollapse (val) {
this.collapsed = val
},
logoRender () {
return <LogoSvg />
},
footerRender () {
return <div>custom footer</div>
}
},
components: {
ProLayout
}
}
</script>
<style lang="less" scoped>
@import "BasicLayout.less";
</style>
import './BasicLayout.less'
import { Layout } from 'ant-design-vue'
import { ContainerQuery } from 'vue-container-query'
import GridContent from './components/GridContent'
import { SiderMenuWrapper, GlobalFooter } from './components'
import './BasicLayout.less'
import { getComponentFormProp, isFun } from './utils/util'
import { SiderMenuProps } from './components/SiderMenu/SiderMenu'
import HeaderView, { HeaderViewProps } from './Header'
......@@ -36,7 +37,6 @@ export const BasicLayoutProps = {
}
}
// eslint-disable-next-line
const MediaQueryEnum = {
'screen-xs': {
maxWidth: 575
......@@ -73,11 +73,8 @@ const BasicLayout = {
name: 'BasicLayout',
functional: true,
props: BasicLayoutProps,
render (h, {
props,
data,
children
}) {
render (h, content) {
const { props, data, children, slots } = content
const {
menus,
layout,
......@@ -86,19 +83,29 @@ const BasicLayout = {
theme,
collapsed,
// eslint-disable-next-line
collapsedButtonRender, autoHideHeader,
footerRender,
autoHideHeader,
mediaQuery,
handleMediaQuery,
handleCollapse
} = props
const footerRender = getComponentFormProp(content, 'footerRender')
const rightContentRender = getComponentFormProp(content, 'rightContentRender')
const collapsedButtonRender = getComponentFormProp(content, 'collapsedButtonRender')
const cdProps = {
...props,
footerRender,
rightContentRender,
collapsedButtonRender
}
return (
<div>
<ContainerQuery query={MediaQueryEnum} onChange={handleMediaQuery}>
<Layout class={{ 'basicLayout': true, ...mediaQuery }}>
<SiderMenuWrapper
{ ...{ props: props } }
{ ...{ props: cdProps } }
menus={menus}
mode={'inline'}
logo={logo}
......@@ -108,7 +115,7 @@ const BasicLayout = {
/>
<Layout class={[layout]} style={{ paddingLeft: '0', minHeight: '100vh' }}>
{headerRender(h, {
...props,
...cdProps,
mode: 'horizontal',
})}
<Layout.Content style={{ margin: '24px 16px', padding: '24px', minHeight: '280px' }}>
......@@ -118,7 +125,7 @@ const BasicLayout = {
</Layout.Content>
<Layout.Footer>
{ footerRender && (
footerRender(h)
isFun(footerRender) && footerRender(h) || footerRender
) || (
<GlobalFooter>
<template slot="links">
......
......@@ -5,6 +5,7 @@ import { Layout } from 'ant-design-vue'
import BaseMenu from './components/RouteMenu/BaseMenu'
import { defaultRenderLogoAntTitle, SiderMenuProps } from './components/SiderMenu/SiderMenu'
import GlobalHeader, { GlobalHeaderProps } from './components/GlobalHeader'
import { isFun } from './utils/util'
const { Header } = Layout
......@@ -20,21 +21,24 @@ export const HeaderViewProps = {
required: true
},
logo: {
type: null,
default: () => null
type: [Function, Object],
required: false
},
autoHideHeader: {
type: Boolean,
required: true
},
menuRender: {
type: null
type: null,
required: false
},
headerRender: {
type: null
type: null,
required: false
},
rightContentRender: {
type: null
type: null,
required: false
},
siderWidth: {
type: Number
......@@ -65,7 +69,7 @@ const renderContent = (h, props) => {
<div class={`${baseCls}-menu`} style={{ maxWidth: `${maxWidth}px`, flex: 1 }}>
<BaseMenu {...{ props: props }} />
</div>
{rightContentRender(h, rightContentProps)}
{isFun(rightContentRender) && rightContentRender(h, rightContentProps) || rightContentRender}
</div>
</div>
)
......
import './index.less'
import debounce from 'lodash/debounce'
import { triggerEvent, inBrowser } from '../../utils/util'
import { triggerEvent, inBrowser, isFun } from '../../utils/util'
import { Icon } from 'ant-design-vue'
import { defaultRenderLogo } from '../SiderMenu/SiderMenu'
......@@ -23,16 +23,15 @@ export const GlobalHeaderProps = {
default: () => null
},
menuRender: {
type: Function,
type: null,
required: false
},
collapsedButtonRender: {
type: Function,
defualt: null,
type: null,
required: false
},
rightContentRender: {
type: Function,
type: null,
required: false
}
}
......@@ -59,7 +58,7 @@ const GlobalHeader = {
if (collapsedButtonRender !== false && menuRender !== false) {
return (
<span class="ant-pro-global-header-trigger" onClick={toggle}>
{collapsedButtonRender(h, collapsed)}
{isFun(collapsedButtonRender) && collapsedButtonRender(h, collapsed) || collapsedButtonRender}
</span>
)
}
......@@ -78,7 +77,7 @@ const GlobalHeader = {
</a>
)}
{renderCollapsedButton()}
{rightContentRender && rightContentRender(h, this.$props)}
{isFun(rightContentRender) && rightContentRender(h, this.$props) || rightContentRender}
</div>
)
},
......
import triggerEvent from 'ant-design-vue/es/_util/triggerEvent'
import { inBrowser } from 'ant-design-vue/es/_util/env'
const getComponentFormProp = (instance, prop) => {
const slots = instance.slots && instance.slots()
return slots[prop] || instance.props[prop]
}
const isFun = (func) => {
return typeof func === 'function'
}
/**
* 触发 window.resize
*/
export {
triggerEvent,
inBrowser
inBrowser,
getComponentFormProp,
isFun
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment