Unverified Commit 078000d6 authored by Sendya's avatar Sendya

fix: PageHeaderWrapper

parent e9176c31
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@ant-design/icons": "^4.0.0-alpha.11", "@ant-design/icons": "^4.0.0-alpha.11",
"ant-design-vue": "^1.5.0-rc.4", "ant-design-vue": "^1.5.3",
"core-js": "^3.1.2", "core-js": "^3.1.2",
"vue-i18n": "^8.15.0", "vue-i18n": "^8.15.0",
"vue-ls": "^3.2.1", "vue-ls": "^3.2.1",
......
// eslint-disable-next-line // eslint-disable-next-line
import BasicLayout from '../layouts/BasicLayout' import BasicLayout from '../layouts/BasicLayout'
const renderRouterView = {
render: (h) => h('router-view')
}
const asyncRouterMap = [ const asyncRouterMap = [
{ {
path: '/', path: '/',
...@@ -14,13 +18,14 @@ const asyncRouterMap = [ ...@@ -14,13 +18,14 @@ const asyncRouterMap = [
name: 'dashboard', name: 'dashboard',
meta: { keepAlive: true, title: 'menu.dashboard.default', icon: 'dashboard' }, meta: { keepAlive: true, title: 'menu.dashboard.default', icon: 'dashboard' },
redirect: '/dashboard/analysis', redirect: '/dashboard/analysis',
component: { render: (h) => h('router-view') }, component: renderRouterView,
children: [ children: [
{ {
path: '/dashboard/analysis', path: '/dashboard/analysis',
name: 'analysis', name: 'analysis',
meta: { meta: {
keepAlive: true, keepAlive: true,
icon: 'smile',
title: 'menu.dashboard.analysis' title: 'menu.dashboard.analysis'
}, },
component: () => import(/* webpackChunkName: "about" */ '../views/BlockPage') component: () => import(/* webpackChunkName: "about" */ '../views/BlockPage')
...@@ -31,6 +36,7 @@ const asyncRouterMap = [ ...@@ -31,6 +36,7 @@ const asyncRouterMap = [
meta: { meta: {
global: true, global: true,
keepAlive: true, keepAlive: true,
icon: 'smile',
title: 'menu.dashboard.workplace' title: 'menu.dashboard.workplace'
}, },
component: () => import(/* webpackChunkName: "about" */ '../views/TestPage') component: () => import(/* webpackChunkName: "about" */ '../views/TestPage')
...@@ -38,59 +44,60 @@ const asyncRouterMap = [ ...@@ -38,59 +44,60 @@ const asyncRouterMap = [
] ]
}, },
{ {
path: '/page2', path: '/form',
name: 'page2', name: 'form',
meta: {
keepAlive: true,
title: 'menu.nav2',
icon: 'video-camera'
},
component: () => import(/* webpackChunkName: "about" */ '../views/TestPage2')
},
{
path: '/page3',
name: 'page3',
meta: {
keepAlive: true,
title: 'menu.nav2',
icon: 'video-camera'
},
component: () => import(/* webpackChunkName: "about" */ '../views/TestPage2')
},
{
path: '/page4',
name: 'page4',
meta: { meta: {
keepAlive: true, keepAlive: true,
title: 'menu.nav2', title: 'menu.form.default',
icon: 'video-camera'
},
component: () => import(/* webpackChunkName: "about" */ '../views/TestPage2')
},
{
path: '/page5',
name: 'page5',
meta: {
keepAlive: true,
title: 'menu.nav2',
icon: 'video-camera' icon: 'video-camera'
}, },
component: () => import(/* webpackChunkName: "about" */ '../views/TestPage2') component: renderRouterView,
children: [
{
path: '/form/basic-form',
name: 'basic-form',
meta: {
keepAlive: true,
icon: 'smile',
title: 'menu.form.basicform'
},
component: () => import(/* webpackChunkName: "about" */ '../views/BlockPage')
},
{
path: '/form/step-form',
name: 'step-form',
meta: {
keepAlive: true,
icon: 'smile',
title: 'menu.form.stepform'
},
component: () => import(/* webpackChunkName: "about" */ '../views/BlockPage')
},
{
path: '/form/advanced-form',
name: 'advanced-form',
meta: {
keepAlive: true,
icon: 'smile',
title: 'menu.form.advancedform'
},
component: () => import(/* webpackChunkName: "about" */ '../views/BlockPage')
}
]
}, },
{ {
path: '/page6', path: '/page1',
name: 'page6', name: 'page1',
meta: { meta: {
keepAlive: true, keepAlive: true,
title: 'menu.nav2', title: 'menu.nav1',
icon: 'video-camera' icon: 'video-camera'
}, },
component: () => import(/* webpackChunkName: "about" */ '../views/TestPage2') component: () => import(/* webpackChunkName: "about" */ '../views/TestPage2')
}, },
{ {
path: '/page7', path: '/page2',
name: 'page7', name: 'page2',
meta: { meta: {
keepAlive: true, keepAlive: true,
title: 'menu.nav2', title: 'menu.nav2',
...@@ -98,13 +105,12 @@ const asyncRouterMap = [ ...@@ -98,13 +105,12 @@ const asyncRouterMap = [
}, },
component: () => import(/* webpackChunkName: "about" */ '../views/TestPage2') component: () => import(/* webpackChunkName: "about" */ '../views/TestPage2')
}, },
{ {
path: '/page8', path: '/page3',
name: 'page8', name: 'page3',
meta: { meta: {
keepAlive: true, keepAlive: true,
title: 'menu.nav2', title: 'menu.nav3',
icon: 'video-camera' icon: 'video-camera'
}, },
component: () => import(/* webpackChunkName: "about" */ '../views/TestPage2') component: () => import(/* webpackChunkName: "about" */ '../views/TestPage2')
......
...@@ -30,6 +30,12 @@ export { ...@@ -30,6 +30,12 @@ export {
export { export {
default as RightOutline default as RightOutline
} from '@ant-design/icons/lib/outline/RightOutline' } from '@ant-design/icons/lib/outline/RightOutline'
export {
default as ArrowLeftOutline
} from '@ant-design/icons/lib/outline/ArrowLeftOutline'
export {
default as ArrowRightOutline
} from '@ant-design/icons/lib/outline/ArrowRightOutline'
export { export {
default as MenuFoldOutline default as MenuFoldOutline
} from '@ant-design/icons/lib/outline/MenuFoldOutline' } from '@ant-design/icons/lib/outline/MenuFoldOutline'
...@@ -54,4 +60,7 @@ export { ...@@ -54,4 +60,7 @@ export {
export { export {
default as LogoutOutline default as LogoutOutline
} from '@ant-design/icons/lib/outline/LogoutOutline' } from '@ant-design/icons/lib/outline/LogoutOutline'
export {
default as SmileOutline
} from '@ant-design/icons/lib/outline/SmileOutline'
/* Layout end */ /* Layout end */
...@@ -3,7 +3,7 @@ import './BasicLayout.less' ...@@ -3,7 +3,7 @@ import './BasicLayout.less'
import { Avatar, Dropdown, Menu, Icon } from 'ant-design-vue' import { Avatar, Dropdown, Menu, Icon } from 'ant-design-vue'
import { asyncRouterMap } from '../config/router.config.js' import { asyncRouterMap } from '../config/router.config.js'
import { i18nRender } from '../locales' import { i18nRender } from '../locales'
import ProLayout from '@ant-design-vue/pro-layout' import ProLayout, { GlobalFooter } from '@ant-design-vue/pro-layout'
import SelectLang from '../components/SelectLang' import SelectLang from '../components/SelectLang'
import LogoSvg from '../assets/logo.svg?inline' import LogoSvg from '../assets/logo.svg?inline'
// import defaultSettings from '@config/defaultSettings' // import defaultSettings from '@config/defaultSettings'
...@@ -61,9 +61,15 @@ const rightContentRender = (h, props) => { ...@@ -61,9 +61,15 @@ const rightContentRender = (h, props) => {
const footerRender = (h, props) => { const footerRender = (h, props) => {
return ( return (
<div class={'footer custom-render'}> <GlobalFooter class={'footer custom-render'}>
<span>footer</span> <template slot="links">
</div> <a href="https://www.github.com/vueComponent/" target="_self">Github</a>
<a href="https://www.github.com/sendya/" target="_self">@Sendya</a>
</template>
<template slot="copyright">
<a href="https://github.com/vueComponent">vueComponent</a>
</template>
</GlobalFooter>
) )
} }
......
...@@ -12,6 +12,25 @@ export default { ...@@ -12,6 +12,25 @@ export default {
analysis: 'Analysis', analysis: 'Analysis',
workplace: 'Workplace' workplace: 'Workplace'
}, },
nav2: 'Nav 2*' form: {
default: 'Form',
basicform: 'Basic Form',
stepform: 'Step Form',
advancedform: 'Advanced Form'
},
nav1: 'Nav 1',
nav2: 'Nav 2',
nav3: 'Nav 3'
},
pages: {
form: {
basicform: {
headers: {
btn1: 'Button1'
},
content: 'Form pages are used to collect or verify information to users, and basic forms are common in scenarios where there are fewer data items.'
}
}
} }
} }
...@@ -8,10 +8,29 @@ export default { ...@@ -8,10 +8,29 @@ export default {
menu: { menu: {
home: '首页', home: '首页',
dashboard: { dashboard: {
default: '仪表盘', default: 'Dashboard',
analysis: '分析页', analysis: '分析页',
workplace: '工作台' workplace: '工作台'
}, },
nav2: '导航2*' form: {
default: '表单页',
basicform: '基础表单',
stepform: '分步表单',
advancedform: '高级表单'
},
nav1: '导航1',
nav2: '导航2',
nav3: '导航3'
},
pages: {
form: {
basicform: {
headers: {
btn1: '按钮1'
},
content: '表单页用于向用户收集或验证信息,基础表单常见于数据项较少的表单场景。'
}
}
} }
} }
...@@ -9,11 +9,14 @@ import i18n from './locales' ...@@ -9,11 +9,14 @@ import i18n from './locales'
import './router/router-guards' import './router/router-guards'
import './core/library' import './core/library'
import { PageHeaderWrapper } from '@ant-design-vue/pro-layout'
import initializer from './core/bootstrap' import initializer from './core/bootstrap'
import './global.less' import './global.less'
Vue.config.productionTip = false Vue.config.productionTip = false
Vue.component('page-header-wrapper', PageHeaderWrapper)
window._vue = new Vue({ window._vue = new Vue({
router, router,
store, store,
......
<template> <template>
<document-title title="BlockPage"> <page-header-wrapper
:tab-list="tabList"
:tab-active-key="tabActiveKey"
:tab-change="(key) => {
this.tabActiveKey = key
console.log('PageHeader::tabChange', key)
}"
:breadcrumb="false"
>
<template slot="content">
<span>{{ $t('pages.form.basicform.content') }}</span>
</template>
<template slot="extraContent">
<div><a-button>{{ $t('pages.form.basicform.headers.btn1') }}</a-button></div>
</template>
<div> <div>
<strong>Block Page</strong> <strong>Block Page</strong>
</div> </div>
</document-title> </page-header-wrapper>
</template> </template>
<script> <script>
export default { export default {
name: 'BlockPage' name: 'BlockPage',
data () {
return {
console: window.console,
tabList: [
{ tab: 'Tab1', key: 'tab1' },
{ tab: 'Tab2', key: 'tab2' },
{ tab: 'Tab3', key: 'tab3' }
],
tabActiveKey: 'tab1'
}
},
methods: {
handleTabChange (key) {
this.tabActiveKey = key
console.log('PageHeader::tabChange', key)
}
}
} }
</script> </script>
......
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
], ],
"peerDependencies": { "peerDependencies": {
"vue": ">=2.5.0", "vue": ">=2.5.0",
"ant-design-vue": "^1.4.6", "ant-design-vue": "^1.5.3",
"umi-request": "^1.2.11", "umi-request": "^1.2.11",
"vue-container-query": "^0.1.0", "vue-container-query": "^0.1.0",
"vue-template-compiler": ">=2.5.0" "vue-template-compiler": ">=2.5.0"
...@@ -56,7 +56,7 @@ ...@@ -56,7 +56,7 @@
"vue-template-compiler": ">=2.5.0" "vue-template-compiler": ">=2.5.0"
}, },
"dependencies": { "dependencies": {
"ant-design-vue": "^1.5.0-rc.4", "ant-design-vue": "^1.5.3",
"classnames": "^2.2.6", "classnames": "^2.2.6",
"insert-css": "^2.0.0", "insert-css": "^2.0.0",
"lodash": "^4.17.15", "lodash": "^4.17.15",
......
...@@ -2,12 +2,12 @@ import './BasicLayout.less' ...@@ -2,12 +2,12 @@ import './BasicLayout.less'
import { Layout } from 'ant-design-vue' import { Layout } from 'ant-design-vue'
import { ContainerQuery } from 'vue-container-query' import { ContainerQuery } from 'vue-container-query'
import GridContent from './components/GridContent'
import { SiderMenuWrapper, GlobalFooter } from './components' import { SiderMenuWrapper, GlobalFooter } from './components'
import { getComponentFormProp, isFun } from './utils/util' import { getComponentFromProp, isFun } from './utils/util'
import { SiderMenuProps } from './components/SiderMenu/SiderMenu' import { SiderMenuProps } from './components/SiderMenu/SiderMenu'
import HeaderView, { HeaderViewProps } from './Header' import HeaderView, { HeaderViewProps } from './Header'
import WrapContent from './WrapContent' import WrapContent from './WrapContent'
import ConfigProvider from '@ant-design-vue/pro-layout/components/ConfigProvider'
export const BasicLayoutProps = { export const BasicLayoutProps = {
...SiderMenuProps, ...SiderMenuProps,
...@@ -75,25 +75,26 @@ const BasicLayout = { ...@@ -75,25 +75,26 @@ const BasicLayout = {
functional: true, functional: true,
props: BasicLayoutProps, props: BasicLayoutProps,
render (h, content) { render (h, content) {
const { props, data, children, slots } = content const { props, children } = content
const { const {
menus, menus,
layout, layout,
logo, logo,
contentWidth, // contentWidth,
theme, // theme,
collapsed, collapsed,
// eslint-disable-next-line // eslint-disable-next-line
autoHideHeader, // autoHideHeader,
mediaQuery, mediaQuery,
handleMediaQuery, handleMediaQuery,
handleCollapse handleCollapse,
i18nRender
} = props } = props
const footerRender = getComponentFormProp(content, 'footerRender') const footerRender = getComponentFromProp(content, 'footerRender')
const rightContentRender = getComponentFormProp(content, 'rightContentRender') const rightContentRender = getComponentFromProp(content, 'rightContentRender')
const collapsedButtonRender = getComponentFormProp(content, 'collapsedButtonRender') const collapsedButtonRender = getComponentFromProp(content, 'collapsedButtonRender')
const menuHeaderRender = getComponentFormProp(content, 'menuHeaderRender') const menuHeaderRender = getComponentFromProp(content, 'menuHeaderRender')
const cdProps = { const cdProps = {
...props, ...props,
...@@ -104,7 +105,7 @@ const BasicLayout = { ...@@ -104,7 +105,7 @@ const BasicLayout = {
} }
return ( return (
<div> <ConfigProvider i18nRender={i18nRender}>
<ContainerQuery query={MediaQueryEnum} onChange={handleMediaQuery}> <ContainerQuery query={MediaQueryEnum} onChange={handleMediaQuery}>
<Layout class={{ 'basicLayout': true, ...mediaQuery }}> <Layout class={{ 'basicLayout': true, ...mediaQuery }}>
<SiderMenuWrapper <SiderMenuWrapper
...@@ -142,7 +143,7 @@ const BasicLayout = { ...@@ -142,7 +143,7 @@ const BasicLayout = {
</Layout> </Layout>
</Layout> </Layout>
</ContainerQuery> </ContainerQuery>
</div> </ConfigProvider>
) )
} }
} }
......
import PropTypes from 'ant-design-vue/es/_util/vue-types'
const ConfigProvider = {
name: 'ConfigProvider',
props: {
i18nRender: PropTypes.any,
},
provide () {
const _self = this
return {
locale: _self.$props.i18nRender
}
},
render () {
const { $scopedSlots } = this
const children = this.children || $scopedSlots.default
return children()
}
}
export default ConfigProvider
...@@ -9,9 +9,10 @@ const { PageHeaderProps } = PageHeader ...@@ -9,9 +9,10 @@ const { PageHeaderProps } = PageHeader
const prefixedClassName = 'ant-pro-page-header-wrap' const prefixedClassName = 'ant-pro-page-header-wrap'
const PageHeaderTabConfig = { const PageHeaderTabConfig = {
tabList: PropTypes.object, tabList: PropTypes.array,
tabActiveKey: PropTypes.string, tabActiveKey: PropTypes.string,
tabProps: PropTypes.object tabProps: PropTypes.object,
tabChange: PropTypes.func
} }
const PageHeaderWrapperProps = { const PageHeaderWrapperProps = {
...@@ -21,6 +22,7 @@ const PageHeaderWrapperProps = { ...@@ -21,6 +22,7 @@ const PageHeaderWrapperProps = {
content: PropTypes.any, content: PropTypes.any,
extraContent: PropTypes.any, extraContent: PropTypes.any,
pageHeaderRender: PropTypes.func, pageHeaderRender: PropTypes.func,
breadcrumb: PropTypes.oneOf([PropTypes.object, false]),
// 包装 pro-layout 才能使用 // 包装 pro-layout 才能使用
i18nRender: PropTypes.any i18nRender: PropTypes.any
...@@ -38,7 +40,7 @@ const renderFooter = (h, tabConfigProps) => { ...@@ -38,7 +40,7 @@ const renderFooter = (h, tabConfigProps) => {
const { const {
tabList, tabList,
tabActiveKey, tabActiveKey,
onTabChange, tabChange: onTabChange,
tabBarExtraContent, tabBarExtraContent,
tabProps, tabProps,
} = tabConfigProps } = tabConfigProps
...@@ -50,7 +52,6 @@ const renderFooter = (h, tabConfigProps) => { ...@@ -50,7 +52,6 @@ const renderFooter = (h, tabConfigProps) => {
if (onTabChange) { if (onTabChange) {
onTabChange(key) onTabChange(key)
} }
this.$emit('tab-change', key)
}} }}
tabBarExtraContent={tabBarExtraContent} tabBarExtraContent={tabBarExtraContent}
{...tabProps} {...tabProps}
...@@ -90,9 +91,9 @@ const defaultPageHeaderRender = (h, props, value, i18nRender) => { ...@@ -90,9 +91,9 @@ const defaultPageHeaderRender = (h, props, value, i18nRender) => {
content, content,
pageHeaderRender, pageHeaderRender,
extraContent, extraContent,
breadcrumb,
...restProps ...restProps
} = props } = props
if (pageHeaderRender) { if (pageHeaderRender) {
return pageHeaderRender({ ...props }) return pageHeaderRender({ ...props })
} }
...@@ -102,9 +103,10 @@ const defaultPageHeaderRender = (h, props, value, i18nRender) => { ...@@ -102,9 +103,10 @@ const defaultPageHeaderRender = (h, props, value, i18nRender) => {
} }
return ( return (
<PageHeader <PageHeader
{...value}
title={i18nRender(pageHeaderTitle)} title={i18nRender(pageHeaderTitle)}
breadcrumb={breadcrumb}
{...props} {...props}
onBack={() => null}
footer={renderFooter(h, restProps)} footer={renderFooter(h, restProps)}
> >
{renderPageHeader(h, content, extraContent)} {renderPageHeader(h, content, extraContent)}
...@@ -116,14 +118,38 @@ const defaultPageHeaderRender = (h, props, value, i18nRender) => { ...@@ -116,14 +118,38 @@ const defaultPageHeaderRender = (h, props, value, i18nRender) => {
const PageHeaderWrapper = { const PageHeaderWrapper = {
name: 'PageHeaderWrapper', name: 'PageHeaderWrapper',
props: PageHeaderWrapperProps, props: PageHeaderWrapperProps,
inject: ['locale'],
render (h) { render (h) {
const children = this.$slots.default const children = this.$slots.default
const content = this.$slots.content
const extraContent = this.$slots.extraContent
const value = useContext(this.$props.route || this.$route) const value = useContext(this.$props.route || this.$route)
const i18n = this.$props.i18nRender || defaultI18nRender const i18n = this.$props.i18nRender || this.locale || defaultI18nRender
const propsBreadcrumb = this.$props.breadcrumb
let breadcrumb = {}
if (propsBreadcrumb === undefined) {
const routes = this.$route.matched.concat().map(route => {
return {
path: route.path,
breadcrumbName: i18n(route.meta.title)
}
})
breadcrumb = { props: { routes }}
}
const props = {
...this.$props,
content,
extraContent,
breadcrumb
}
return ( return (
<div class="ant-pro-page-header-wrap"> <div class="ant-pro-page-header-wrap">
<div class={`${prefixedClassName}-page-header-warp`}> <div class={`${prefixedClassName}-page-header-warp`}>
<GridContent>{defaultPageHeaderRender(h, this.$props, value, i18n)}</GridContent> <GridContent>{defaultPageHeaderRender(h, props, value, i18n)}</GridContent>
</div> </div>
{ children ? ( { children ? (
<GridContent> <GridContent>
......
import BasicLayout, { BasicLayoutProps } from './BasicLayout' import BasicLayout, { BasicLayoutProps } from './BasicLayout'
import BlockLayout from './BlockLayout' import BlockLayout from './BlockLayout'
import PageHeaderWrapper from './components/PageHeaderWrapper' import PageHeaderWrapper from './components/PageHeaderWrapper'
import GlobalFooter from './components/GlobalFooter'
import DocumentTitle from './components/DocumentTitle' import DocumentTitle from './components/DocumentTitle'
import { updateTheme } from './utils/dynamicTheme' import { updateTheme } from './utils/dynamicTheme'
export { export {
GlobalFooter,
PageHeaderWrapper, PageHeaderWrapper,
BlockLayout, BlockLayout,
DocumentTitle, DocumentTitle,
......
import triggerEvent from 'ant-design-vue/es/_util/triggerEvent' import triggerEvent from 'ant-design-vue/es/_util/triggerEvent'
import { inBrowser } from 'ant-design-vue/es/_util/env' import { inBrowser } from 'ant-design-vue/es/_util/env'
const getComponentFormProp = (instance, prop) => { const getComponentFromProp = (instance, prop) => {
const slots = instance.slots && instance.slots() const slots = instance.slots && instance.slots()
return slots[prop] || instance.props[prop] return slots[prop] || instance.props[prop]
} }
/*const getComponentFromProp = (instance, prop) => {
const slots = instance.$slots
return slots[prop] || instance.$props[prop]
}*/
const isFun = (func) => { const isFun = (func) => {
return typeof func === 'function' return typeof func === 'function'
} }
...@@ -16,6 +22,6 @@ const isFun = (func) => { ...@@ -16,6 +22,6 @@ const isFun = (func) => {
export { export {
triggerEvent, triggerEvent,
inBrowser, inBrowser,
getComponentFormProp, getComponentFromProp,
isFun 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