增加基础页面的布局控件
This commit is contained in:
parent
d467e20dba
commit
b3fcdf4c1b
|
|
@ -71,4 +71,10 @@
|
|||
height: auto !important;
|
||||
_height: @height;
|
||||
}
|
||||
.flex-start(@type: row) {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
flex-direction: @type;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,161 @@
|
|||
<template>
|
||||
<a-layout id="components-layout-demo-fixed-sider">
|
||||
<a-layout-sider :trigger="null" v-model="collapsed" collapsible>
|
||||
<div class="logo">
|
||||
管理系统
|
||||
</div>
|
||||
<a-menu theme="dark" mode="inline" :default-selected-keys="['4']">
|
||||
<a-menu-item key="1">
|
||||
<a-icon type="user" />
|
||||
<span class="nav-text">nav 1</span>
|
||||
</a-menu-item>
|
||||
<a-menu-item key="2">
|
||||
<a-icon type="video-camera" />
|
||||
<span class="nav-text">nav 2</span>
|
||||
</a-menu-item>
|
||||
<a-menu-item key="3">
|
||||
<a-icon type="upload" />
|
||||
<span class="nav-text">nav 3</span>
|
||||
</a-menu-item>
|
||||
<a-menu-item key="4">
|
||||
<a-icon type="bar-chart" />
|
||||
<span class="nav-text">nav 4</span>
|
||||
</a-menu-item>
|
||||
<a-menu-item key="5">
|
||||
<a-icon type="cloud-o" />
|
||||
<span class="nav-text">nav 5</span>
|
||||
</a-menu-item>
|
||||
<a-menu-item key="6">
|
||||
<a-icon type="appstore-o" />
|
||||
<span class="nav-text">nav 6</span>
|
||||
</a-menu-item>
|
||||
<a-menu-item key="7">
|
||||
<a-icon type="team" />
|
||||
<span class="nav-text">nav 7</span>
|
||||
</a-menu-item>
|
||||
<a-menu-item key="8">
|
||||
<a-icon type="shop" />
|
||||
<span class="nav-text">nav 8</span>
|
||||
</a-menu-item>
|
||||
</a-menu>
|
||||
</a-layout-sider>
|
||||
<a-layout >
|
||||
<a-layout-header
|
||||
style="background: #fff; padding: 0"
|
||||
ref="header"
|
||||
:title="pageTitle"
|
||||
:breadcrumb="{ props: { routes } }"
|
||||
>
|
||||
<div class="header-con">
|
||||
|
||||
<a-icon
|
||||
class="trigger"
|
||||
:type="collapsed ? 'menu-unfold' : 'menu-fold'"
|
||||
@click="() => (collapsed = !collapsed)"
|
||||
/>
|
||||
<a-icon type="arrow-left" style="font-size: 18px; padding-right: 24px;" />
|
||||
<a-breadcrumb :routes="routes">
|
||||
<template slot="itemRender" slot-scope="{ route, params, routes, paths }">
|
||||
<span v-if="routes.indexOf(route) === routes.length - 1">
|
||||
{{ route.breadcrumbName }}
|
||||
</span>
|
||||
<router-link v-else :to="`/${paths.join('/')}`">
|
||||
{{ route.breadcrumbName }}
|
||||
</router-link>
|
||||
</template>
|
||||
</a-breadcrumb>
|
||||
</div>
|
||||
|
||||
|
||||
</a-layout-header>
|
||||
<a-layout-content :style="contentStyle">
|
||||
<div :style="containerStyle">
|
||||
<nuxt/>
|
||||
</div>
|
||||
</a-layout-content>
|
||||
<!-- <a-layout-footer :style="{ textAlign: 'center' }" ref="footer">
|
||||
Ant Design ©2018 Created by Ant UED
|
||||
</a-layout-footer>-->
|
||||
</a-layout>
|
||||
</a-layout>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "manager",
|
||||
data () {
|
||||
return {
|
||||
collapsed: false,
|
||||
headerHeight: 0,
|
||||
footerHeight: 0,
|
||||
routes: [
|
||||
{
|
||||
path: 'index',
|
||||
breadcrumbName: 'First-level Menu',
|
||||
},
|
||||
],
|
||||
pageTitle: '123'
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
contentStyle () {
|
||||
return {
|
||||
margin: '24px 16px 24px',
|
||||
overflow: 'inherit',
|
||||
height: `calc(100vh - ${this.headerHeight + this.footerHeight + 48}px)`,
|
||||
}
|
||||
},
|
||||
containerStyle () {
|
||||
return {
|
||||
padding: '24px',
|
||||
background: '#fff',
|
||||
textAlign: 'center',
|
||||
height: `100%`,
|
||||
overflow: 'auto',
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
this.$nextTick( () => {
|
||||
if (this.$refs.header) {
|
||||
this.headerHeight = this.$refs.header.$el.offsetHeight
|
||||
// this.footerHeight = this.$refs.footer.$el.offsetHeight
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
#components-layout-demo-fixed-sider {
|
||||
.header-con {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
}
|
||||
.trigger:hover {
|
||||
color: #1890ff;
|
||||
}
|
||||
.trigger {
|
||||
font-size: 18px;
|
||||
line-height: 64px;
|
||||
padding: 0 24px;
|
||||
cursor: pointer;
|
||||
transition: color 0.3s;
|
||||
}
|
||||
.logo {
|
||||
width: 80%;
|
||||
padding: 0 10px;
|
||||
height: 31px;
|
||||
background: rgba(255, 255, 255, 0.2);
|
||||
margin: 16px auto 16px;
|
||||
line-height: 31px;
|
||||
text-align: center;
|
||||
color: #fff;
|
||||
font-size: 18px;
|
||||
overflow: inherit;
|
||||
|
||||
//
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -17,7 +17,9 @@ export default {
|
|||
],
|
||||
link: [
|
||||
{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }
|
||||
]
|
||||
],
|
||||
css: [],
|
||||
js: []
|
||||
},
|
||||
|
||||
// Global CSS: https://go.nuxtjs.dev/config-css
|
||||
|
|
|
|||
|
|
@ -0,0 +1,15 @@
|
|||
<template>
|
||||
<div>test</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import base from "~/templates/base";
|
||||
export default {
|
||||
name: "test",
|
||||
extends: base,
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
<template>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "index"
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
export default {
|
||||
name: "manager",
|
||||
layout: 'manager'
|
||||
}
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
import {recursionTree} from "./utils";
|
||||
|
||||
const mapComponents = {
|
||||
complete: 'a-auto-complete',
|
||||
cascader: 'a-cascader',
|
||||
checkbox: 'a-checkbox-group',
|
||||
radio: 'a-radio-group',
|
||||
datePicker: 'a-date-picker',
|
||||
monthPicker: 'a-month-picker',
|
||||
rangePicker: 'a-range-picker',
|
||||
weekPicker: 'a-week-picker',
|
||||
timePicker: 'a-time-picker',
|
||||
input: 'a-input',
|
||||
rate: 'a-rate',
|
||||
slider: 'a-slider',
|
||||
switch: 'a-switch',
|
||||
upload: 'a-upload',
|
||||
button: 'a-button',
|
||||
inputNumber: 'a-input-number',
|
||||
mentions: ['a-mentions', 'a-mentions-option'],
|
||||
select: ['a-select', 'a-select-option'],
|
||||
treeSelect: ['a-tree-select', 'a-tree-select-node'],
|
||||
}
|
||||
|
||||
export default function createControlComponent (h, componentType, vueCreateElementProps = {}) {
|
||||
const component = mapComponents[componentType]
|
||||
// 没有子组件的情况下直接导出
|
||||
if (typeof component === "string") {
|
||||
return h(component, vueCreateElementProps)
|
||||
}
|
||||
// 子组件进行判断是否提供子内容
|
||||
const { props } = vueCreateElementProps
|
||||
if (!props.children || !Array.isArray(props.children)) {
|
||||
return null
|
||||
}
|
||||
const [ outer, inner ] = component
|
||||
|
||||
return h(
|
||||
outer,
|
||||
vueCreateElementProps,
|
||||
recursionTree(props.children, (node) => {
|
||||
const {label, value, ...otherProps} = node
|
||||
return h(inner, {
|
||||
props: {
|
||||
value: value,
|
||||
title: label,
|
||||
...otherProps
|
||||
}
|
||||
}, [h(label)])
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
/**
|
||||
* 创建具有栅格化的表单项
|
||||
* @param h
|
||||
* @param formItemProps
|
||||
* @param rowConfig
|
||||
* @param colConfig
|
||||
* @param children
|
||||
* @returns {*}
|
||||
*/
|
||||
export default function createFormComponent(h, formItemProps, rowConfig, colConfig, children = []) {
|
||||
if (rowConfig) {
|
||||
return h('a-row', rowConfig, [
|
||||
h('a-col', colConfig, [
|
||||
h('a-form-item', formItemProps, children)
|
||||
])
|
||||
])
|
||||
}
|
||||
|
||||
return h('a-form-item', formItemProps, children)
|
||||
}
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
import createControlComponent from "./createControlComponent";
|
||||
import createFormComponent from "./createFormComponent";
|
||||
|
||||
export default {
|
||||
name: 'dynamicForm',
|
||||
props: {
|
||||
/**
|
||||
* 表单配置项
|
||||
*/
|
||||
formOption: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
},
|
||||
/**
|
||||
* 控件列表配置项
|
||||
*/
|
||||
options: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
|
||||
/**
|
||||
* 表单全局列配置
|
||||
*/
|
||||
colOption: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
},
|
||||
|
||||
/**
|
||||
* 表单全局行配置
|
||||
*/
|
||||
rowOption: {
|
||||
type: Object,
|
||||
default: null
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
||||
/**
|
||||
* 校验结果,正确触发回调
|
||||
* @param cb
|
||||
*/
|
||||
validate (cb) {},
|
||||
|
||||
/**
|
||||
* 重置表单内容
|
||||
*/
|
||||
reset () {}
|
||||
},
|
||||
|
||||
render (h) {
|
||||
return h(
|
||||
'a-form-model',
|
||||
this.formOption,
|
||||
this.options.map(({ type, formItemOption, elementOption }) => {
|
||||
return createFormComponent(
|
||||
h, formItemOption,
|
||||
this.rowOption,
|
||||
this.colOption,
|
||||
[createControlComponent(h, type, elementOption)]
|
||||
)
|
||||
})
|
||||
)
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
/**
|
||||
* 递归处理树节点
|
||||
* @param treeNodes
|
||||
* @param cb
|
||||
* @returns {*[]}
|
||||
*/
|
||||
export const recursionTree = function (treeNodes, cb) {
|
||||
return ([].concat(treeNodes)).map(node => {
|
||||
if (node.children && node.children.length > 0) {
|
||||
node.children = recursionTree(node.children, cb)
|
||||
}
|
||||
return cb(node)
|
||||
})
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
import base from './base'
|
||||
export default {
|
||||
name: "form",
|
||||
extends: base
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
<template>
|
||||
<a-layout>
|
||||
|
||||
</a-layout>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import base from './base'
|
||||
|
||||
export default {
|
||||
name: 'table',
|
||||
extends: base,
|
||||
data () {
|
||||
return {
|
||||
dataSource: [],
|
||||
loading: false,
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
Loading…
Reference in New Issue