diff --git a/devui/layout/component/aside/index.tsx b/devui/layout/component/aside/index.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..9856f0f1c0ce94f844629307030820bfb6052704
--- /dev/null
+++ b/devui/layout/component/aside/index.tsx
@@ -0,0 +1,12 @@
+import { defineComponent } from 'vue'
+export default defineComponent({
+ name: 'DAside',
+ render() {
+ const { $slots } = this
+ const children = $slots.default?.()
+
+ return
+ {children}
+
+ }
+})
\ No newline at end of file
diff --git a/devui/layout/component/content/index.scss b/devui/layout/component/content/index.scss
new file mode 100644
index 0000000000000000000000000000000000000000..d1999322b754cc3a1c6c61f0b080b000f5a26ae0
--- /dev/null
+++ b/devui/layout/component/content/index.scss
@@ -0,0 +1,6 @@
+.d-content {
+ flex: auto;
+
+ /* fix firefox can't set height smaller than content on flex item */
+ min-height: 0;
+}
diff --git a/devui/layout/component/content/index.tsx b/devui/layout/component/content/index.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..68deaa492bc892dbc9b8fcd287f2db2fd8d061f8
--- /dev/null
+++ b/devui/layout/component/content/index.tsx
@@ -0,0 +1,13 @@
+import { defineComponent } from 'vue'
+import './index.scss'
+export default defineComponent({
+ name: 'DContent',
+ render() {
+ const { $slots } = this
+ const children = $slots.default?.()
+
+ return
+ {children}
+
+ }
+})
\ No newline at end of file
diff --git a/devui/layout/component/footer/index.scss b/devui/layout/component/footer/index.scss
new file mode 100644
index 0000000000000000000000000000000000000000..dcd0b6946640f2c9d80cce0cde37f539c465fc8e
--- /dev/null
+++ b/devui/layout/component/footer/index.scss
@@ -0,0 +1,4 @@
+.d-footer {
+ text-align: center;
+ line-height: 1.5;
+}
diff --git a/devui/layout/component/footer/index.tsx b/devui/layout/component/footer/index.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..6354bc67717e145a95658d388ace79fad91de306
--- /dev/null
+++ b/devui/layout/component/footer/index.tsx
@@ -0,0 +1,13 @@
+import { defineComponent } from 'vue'
+import './index.scss'
+export default defineComponent({
+ name: 'DFooter',
+ render() {
+ const { $slots } = this
+ const children = $slots.default?.()
+
+ return
+ }
+})
\ No newline at end of file
diff --git a/devui/layout/component/header/index.scss b/devui/layout/component/header/index.scss
new file mode 100644
index 0000000000000000000000000000000000000000..308673509a72eac29142e6c159ba551ea481cead
--- /dev/null
+++ b/devui/layout/component/header/index.scss
@@ -0,0 +1,4 @@
+.d-header {
+ flex: 0 0 auto;
+ min-height: 40px;
+}
diff --git a/devui/layout/component/header/index.tsx b/devui/layout/component/header/index.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..3695b2ccf010583c27ff59cc49baf78edddf2a67
--- /dev/null
+++ b/devui/layout/component/header/index.tsx
@@ -0,0 +1,13 @@
+import { defineComponent } from 'vue'
+import './index.scss'
+export default defineComponent({
+ name: 'DHeader',
+ render() {
+ const { $slots } = this
+ const children = $slots.default?.()
+
+ return
+ }
+})
\ No newline at end of file
diff --git a/devui/layout/index.ts b/devui/layout/index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..ccea0cfe6d881a4a8b2b23b19595e156d0db8263
--- /dev/null
+++ b/devui/layout/index.ts
@@ -0,0 +1,23 @@
+import type { App } from 'vue'
+import Layout from './src/layout'
+import Aside from './component/aside'
+import Header from './component/header'
+import Content from './component/content'
+import Footer from './component/footer'
+Layout.install = function (app: App) {
+ app.component(Layout.name, Layout)
+ app.component(Aside.name, Aside)
+ app.component(Header.name, Header)
+ app.component(Content.name, Content)
+ app.component(Footer.name, Footer)
+}
+
+export { Layout, Aside, Header, Content, Footer }
+
+export default {
+ title: 'Layout 布局',
+ category: '通用',
+ install(app: App): void {
+ app.use(Layout as any)
+ }
+}
diff --git a/devui/layout/src/layout-types.ts b/devui/layout/src/layout-types.ts
new file mode 100644
index 0000000000000000000000000000000000000000..9f7fbea17d29a725f78792ad8c036c97cc34f51d
--- /dev/null
+++ b/devui/layout/src/layout-types.ts
@@ -0,0 +1,9 @@
+import type { ExtractPropTypes } from 'vue'
+
+export const layoutProps = {
+ /* test: {
+ type: Object as PropType<{ xxx: xxx }>
+ } */
+} as const
+
+export type LayoutProps = ExtractPropTypes
diff --git a/devui/layout/src/layout.scss b/devui/layout/src/layout.scss
new file mode 100644
index 0000000000000000000000000000000000000000..f2362c984d80542b3dd8aa80cc4aceb4f9feeb9a
--- /dev/null
+++ b/devui/layout/src/layout.scss
@@ -0,0 +1,9 @@
+.d-layout {
+ display: flex;
+ flex: auto;
+ flex-direction: column;
+
+ &-aside {
+ flex-direction: row;
+ }
+}
diff --git a/devui/layout/src/layout.tsx b/devui/layout/src/layout.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..c8afaa30867d035c19bbf6319ecf32fa23201604
--- /dev/null
+++ b/devui/layout/src/layout.tsx
@@ -0,0 +1,17 @@
+import './layout.scss'
+
+import { defineComponent } from 'vue'
+import { layoutProps, LayoutProps } from './layout-types'
+
+export default defineComponent({
+ name: 'DLayout',
+ props: layoutProps,
+ render() {
+ const children = this.$slots.default?.()
+ const layoutAsideClz = children.find(item => item.type.name === 'DAside') ? 'd-layout-aside' : ''
+ const layoutClaszz = `d-layout ${layoutAsideClz}`
+ return
+ {children}
+
+ }
+})
diff --git a/docs/components/layout/index.md b/docs/components/layout/index.md
new file mode 100644
index 0000000000000000000000000000000000000000..a39e1609375d7162b1975a924ca78eff834f60fd
--- /dev/null
+++ b/docs/components/layout/index.md
@@ -0,0 +1,149 @@
+# Layout 布局
+
+页面的布局方式。
+
+**何时使用**
+
+当用户需要直接使用一些既有布局时。
+
+### 基本用法
+
+:::demo
+
+```vue
+
+ Header
+ Content
+ Footer
+
+
+
+ Header
+
+ Aside
+ Content
+
+ Footer
+
+
+
+ Header
+
+ Content
+ Aside
+
+ Footer
+
+
+
+ Aside
+
+ Header
+ Content
+ Footer
+
+
+```
+:::
+# d-layout
+
+布局容器,可以与`d-header`, `d-content`, `d-footer`, `d-aside`组合实现布局;
+`d-layout`下可嵌套元素:`d-header`, `d-content`, `d-aside`, `d-layout`。
+# d-header
+
+顶部布局,只能放在`d-layout`容器中,作为`d-layout`容器的顶部实现。
+默认高度:40px。
+# d-footer
+
+底部布局,只能放在`d-layout`容器中,作为`d-layout`容器的底部实现。
+
+# d-content
+
+内容容器,只能放在`d-layout`容器中,作为`d-layout`容器`d-header`与`d-footer`之间的内容。
+# d-aside
+
+侧边栏,只能放在`d-layout`容器中,作为`d-layout`容器的侧边栏部分。
+
+scss 样式
+```scss
+.basic-usage {
+ box-shadow: 0 1px 4px 0;
+ margin-top: 36px;
+
+ &:first-child {
+ margin-top: 0;
+ }
+}
+
+.d-header {
+ text-align: center;
+ line-height: 40px;
+ background-color: #333854;
+ color: #ffffff;
+}
+
+.d-aside {
+ min-height: 200px;
+ min-width: 120px;
+ text-align: center;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ background-color: #f8f8f8;
+}
+
+.d-content {
+ line-height: 200px;
+ text-align: center;
+ background-color: #ffffff;
+}
+
+.d-footer {
+ color: #ffffff;
+ background-color: #333854;
+ padding: 8px 24px;
+}
+
+```
+
+
\ No newline at end of file