Commit 9a909150 by Sendya

Added AdvancedForm

parent 25b475bb
<template>
<a-popover trigger="click" placement="bottomRight">
<template slot="content">
<a-spin :spinning="loadding">
<a-tabs>
<a-tab-pane tab="通知" key="1">
<a-list>
<a-list-item>
<a-list-item-meta title="你收到了 14 份新周报" description="一年前">
<a-avatar style="background-color: white" slot="avatar" src="https://gw.alipayobjects.com/zos/rmsportal/ThXAXghbEsBCCSDihZxY.png"/>
</a-list-item-meta>
</a-list-item>
<a-list-item>
<a-list-item-meta title="你推荐的 曲妮妮 已通过第三轮面试" description="一年前">
<a-avatar style="background-color: white" slot="avatar" src="https://gw.alipayobjects.com/zos/rmsportal/OKJXDXrmkNshAMvwtvhu.png"/>
</a-list-item-meta>
</a-list-item>
<a-list-item>
<a-list-item-meta title="这种模板可以区分多种通知类型" description="一年前">
<a-avatar style="background-color: white" slot="avatar" src="https://gw.alipayobjects.com/zos/rmsportal/kISTdvpyTAhtGxpovNWd.png"/>
</a-list-item-meta>
</a-list-item>
</a-list>
</a-tab-pane>
<a-tab-pane tab="消息" key="2">
123
</a-tab-pane>
<a-tab-pane tab="待办" key="3">
123
</a-tab-pane>
</a-tabs>
</a-spin>
</template>
<span @click="fetchNotice" class="header-notice">
<a-badge count="12">
<a-icon style="font-size: 16px; padding: 4px" type="bell" />
</a-badge>
</span>
</a-popover>
</template>
<script>
export default {
name: "HeaderNotice",
data () {
return {
loadding: false
}
},
methods: {
fetchNotice () {
if (this.loadding) {
this.loadding = false
return
}
this.loadding = true
setTimeout(() => {
this.loadding = false
}, 2000)
}
}
}
</script>
<style lang="scss" scoped>
.header-notice{
display: inline-block;
transition: all 0.3s;
span {
vertical-align: initial;
}
}
</style>
\ No newline at end of file
......@@ -6,11 +6,7 @@
<span class="action">
<a-icon type="question-circle-o"></a-icon>
</span>
<span class="action">
<a-badge count="12">
<a-icon class="icon" type="bell"></a-icon>
</a-badge>
</span>
<header-notice class="action"/>
<a-dropdown>
<span class="action ant-dropdown-link user-dropdown-menu">
<a-avatar class="avatar" size="small" :src="avatar()"/>
......@@ -44,10 +40,14 @@
</template>
<script>
import HeaderNotice from './HeaderNotice'
import { mapActions, mapGetters } from 'vuex'
export default {
name: "LayoutHeader",
components: {
HeaderNotice
},
props: {
collapsed: {
type: Boolean,
......
// import table from './datatable.vue';
// import table from './table.vue';
// export default table;
import T from "ant-design-vue/es/table/Table";
export default {
data() {
return {
localDataSource: [],
localPagination: Object.assign({}, T.props.pagination)
};
},
props: Object.assign({}, T.props, {
data: {
type: Function,
required: true
},
pageNum: {
type: Number,
default: 1
},
pageSize: {
type: Number,
default: 10
},
showSizeChanger: {
type: Boolean,
default: true
}
}),
watch: {
'localPagination.current' (val) {
this.$router.push({
name: this.$route.name,
params: Object.assign({}, this.$route.params, {
pageNo: val
}),
});
},
pageNum(val) {
this.localPagination = Object.assign({}, this.localPagination, {
current: val
});
},
pageSize(val) {
this.localPagination = Object.assign({}, this.localPagination, {
pageSize: val
});
},
showSizeChanger(val) {
this.localPagination = Object.assign({}, this.localPagination, {
showSizeChanger: val
});
}
},
created() {
this.localPagination = Object.assign({}, this.localPagination, {
current: this.pageNum,
pageSize: this.pageSize,
showSizeChanger: this.showSizeChanger
});
this.loadData();
},
methods: {
refresh() {
this.loadData();
},
loadData(pagination, filters, sorter) {
var result = this.data(
Object.assign({
pageNo:
(pagination && pagination.current) ||
this.localPagination.current,
pageSize:
(pagination && pagination.pageSize) ||
this.localPagination.pageSize
},
(sorter && sorter.field && {
sortField: sorter.field
}) || {},
(sorter && sorter.order && {
sortOrder: sorter.order
}) || {}, {
...filters
}
)
);
if (result instanceof Promise) {
result.then(r => {
this.localPagination = Object.assign({}, this.localPagination, {
current: r.current_page, //current: r.pageNo,
total: r.total, //total: r.totalCount,
showSizeChanger: this.showSizeChanger,
pageSize: (pagination && pagination.pageSize) ||
this.localPagination.pageSize
});
this.localDataSource = r.data; // this.localDataSource = r.result;
});
}
}
},
render(h) {
var _vm = this
var props = {},
localKeys = Object.keys(this.$data);
Object.keys(T.props).forEach(k => {
var localKey = `local${k.substring(0,1).toUpperCase()}${k.substring(1)}`;
if (localKeys.includes(localKey)) {
return props[k] = _vm[localKey];
}
return props[k] = _vm[k];
})
return h("a-table", {
tag: "component",
attrs: props,
on: {
change: _vm.loadData
},
scopedSlots: this.$scopedSlots
});
}
};
<template>
<div class="toolbar">
<div style="float: left">
<slot name="extra"></slot>
</div>
<div style="float: right">
<slot></slot>
</div>
</div>
</template>
<script>
export default {
name: "FooterToolBar"
}
</script>
<style lang="scss" scoped>
.toolbar {
position: fixed;
width: 100%;
bottom: 0;
right: 0;
height: 56px;
line-height: 56px;
box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.03);
background: #fff;
border-top: 1px solid #e8e8e8;
padding: 0 24px;
z-index: 9;
}
</style>
\ No newline at end of file
......@@ -98,7 +98,7 @@ export const asyncRouterMap = [
{
path: '/form/advanced-form',
name: 'AdvanceForm',
component: () => import('../views/form/BasicForm'),
component: () => import('../views/form/advancedForm/AdvancedForm'),
meta: { title: '高级表单' }
}
]
......
......@@ -7,7 +7,7 @@
<h1>{{config[type].title}}</h1>
<div class="desc">{{config[type].desc}}</div>
<div class="action">
<a-button type="primary">返回首页</a-button>
<a-button type="primary" @click="handleToHome">返回首页</a-button>
</div>
</div>
</div>
......@@ -23,6 +23,11 @@
return {
config: types
}
},
methods: {
handleToHome () {
this.$router.push({ name: 'dashboard' })
}
}
}
</script>
......
<template>
<div>
<a-card class="card" title="仓库管理" :bordered="false">
<repository-form ref="repository" :showSubmit="false" />
</a-card>
<a-card class="card" title="任务管理" :bordered="false">
<task-form ref="task" :showSubmit="false" />
</a-card>
<!-- table -->
<a-card>
<form :autoFormCreate="(form) => this.form = form">
<a-table
:columns="columns"
:dataSource="data"
:pagination="false"
>
<template v-for="(col, i) in ['name', 'workId', 'department']" :slot="col" slot-scope="text, record, index">
<a-input
:key="col"
v-if="record.editable"
style="margin: -5px 0"
:value="text"
:placeholder="columns[i].title"
@change="e => handleChange(e.target.value, record.key, col)"
/>
<template v-else>{{text}}</template>
</template>
<template slot="operation" slot-scope="text, record, index">
<template v-if="record.editable">
<span v-if="record.isNew">
<a @click="saveRow(record.key)">添加</a>
<a-divider type="vertical" />
<a-popconfirm title="是否要删除此行?" @confirm="remove(record.key)">
<a>删除</a>
</a-popconfirm>
</span>
<span v-else>
<a @click="saveRow(record.key)">保存</a>
<a-divider type="vertical" />
<a @click="cancle(record.key)">取消</a>
</span>
</template>
<span v-else>
<a @click="toggle(record.key)">编辑</a>
<a-divider type="vertical" />
<a-popconfirm title="是否要删除此行?" @confirm="remove(record.key)">
<a>删除</a>
</a-popconfirm>
</span>
</template>
</a-table>
<a-button style="width: 100%; margin-top: 16px; margin-bottom: 8px" type="dashed" icon="plus" @click="newMeber">新增成员</a-button>
</form>
</a-card>
<!-- fixed footer toolbar -->
<footer-tool-bar>
<a-button type="primary" @click="validate" :loading="loading">提交</a-button>
</footer-tool-bar>
</div>
</template>
<script>
import RepositoryForm from './RepositoryForm'
import TaskForm from './TaskForm'
import FooterToolBar from '@/components/tools/FooterToolBar'
export default {
name: "AdvancedForm",
components: {
FooterToolBar,
RepositoryForm,
TaskForm
},
data () {
return {
desc: '高级表单常见于一次性输入和提交大批量数据的场景。',
loading: false,
// table
columns: [
{
title: '成员姓名',
dataIndex: 'name',
key: 'name',
width: '20%',
scopedSlots: { customRender: 'name' }
},
{
title: '工号',
dataIndex: 'workId',
key: 'workId',
width: '20%',
scopedSlots: { customRender: 'workId' }
},
{
title: '所属部门',
dataIndex: 'department',
key: 'department',
width: '40%',
scopedSlots: { customRender: 'department' }
},
{
title: '操作',
key: 'action',
scopedSlots: { customRender: 'operation' }
}
],
data: [
{
key: '1',
name: '小明',
workId: '001',
editable: false,
department: '行政部'
},
{
key: '2',
name: '李莉',
workId: '002',
editable: false,
department: 'IT部'
},
{
key: '3',
name: '王小帅',
workId: '003',
editable: false,
department: '财务部'
}
]
}
},
methods: {
handleSubmit (e) {
e.preventDefault()
},
newMeber () {
this.data.push({
key: '-1',
name: '',
workId: '',
department: '',
editable: true,
isNew: true
})
},
remove (key) {
const newData = this.data.filter(item => item.key !== key)
this.data = newData
},
saveRow (key) {
let target = this.data.filter(item => item.key === key)[0]
target.editable = false
target.isNew = false
},
toggle (key) {
let target = this.data.filter(item => item.key === key)[0]
target.editable = !target.editable
},
getRowByKey (key, newData) {
const data = this.data
return (newData || data).filter(item => item.key === key)[0]
},
cancle (key) {
let target = this.data.filter(item => item.key === key)[0]
target.editable = false
},
handleChange (value, key, column) {
const newData = [...this.data]
const target = newData.filter(item => key === item.key)[0]
if (target) {
target[column] = value
this.data = newData
}
},
// 最终全页面提交
validate () {
this.$refs.repository.form.validateFields((err, values) => {
if (!err) {
this.$notification['error']({
message: 'Received values of form:',
description: values
})
}
})
this.$refs.task.form.validateFields((err, values) => {
if (!err) {
this.$notification['error']({
message: 'Received values of form:',
description: values
})
}
})
}
}
}
</script>
<style lang="scss" scoped>
.card{
margin-bottom: 24px;
}
</style>
\ No newline at end of file
<template>
<a-form @submit="handleSubmit" :autoFormCreate="(form) => this.form = form" class="form">
<a-row class="form-row">
<a-col :lg="6" :md="12" :sm="24">
<a-form-item
label="仓库名"
fieldDecoratorId="repository.name"
:fieldDecoratorOptions="{rules: [{ required: true, message: '请输入仓库名称', whitespace: true}]}"
>
<a-input placeholder="请输入仓库名称" />
</a-form-item>
</a-col>
<a-col :xl="{span: 7, offset: 1}" :lg="{span: 8}" :md="{span: 12}" :sm="24">
<a-form-item
label="仓库域名"
fieldDecoratorId="repository.domain"
:fieldDecoratorOptions="{rules: [{ required: true, message: '请输入仓库域名', whitespace: true}, {validator: validate}]}"
>
<a-input addonBefore="http://" addonAfter=".github.io" placeholder="请输入"/>
</a-form-item>
</a-col>
<a-col :xl="{span: 9, offset: 1}" :lg="{span: 10}" :md="{span: 24}" :sm="24">
<a-form-item
label="仓库管理员"
fieldDecoratorId="repository.manager"
:fieldDecoratorOptions="{rules: [{ required: true, message: '请选择管理员'}]}"
>
<a-select placeholder="请选择管理员">
<a-select-option value="王同学">王同学</a-select-option>
<a-select-option value="李同学">李同学</a-select-option>
<a-select-option value="黄同学">黄同学</a-select-option>
</a-select>
</a-form-item>
</a-col>
</a-row>
<a-row class="form-row">
<a-col :lg="6" :md="12" :sm="24">
<a-form-item
label="审批人"
fieldDecoratorId="repository.auditor"
:fieldDecoratorOptions="{rules: [{ required: true, message: '请选择审批员'}]}"
>
<a-select placeholder="请选择审批员">
<a-select-option value="王晓丽">王晓丽</a-select-option>
<a-select-option value="李军">李军</a-select-option>
</a-select>
</a-form-item>
</a-col>
<a-col :xl="{span: 7, offset: 1}" :lg="{span: 8}" :md="{span: 12}" :sm="24">
<a-form-item
label="生效日期"
fieldDecoratorId="repository.effectiveDate"
:fieldDecoratorOptions="{rules: [{ required: true, message: '请选择生效日期'}]}"
>
<a-range-picker style="width: 100%" />
</a-form-item>
</a-col>
<a-col :xl="{span: 9, offset: 1}" :lg="{span: 10}" :md="{span: 24}" :sm="24">
<a-form-item
label="仓库类型"
fieldDecoratorId="repository.type"
:fieldDecoratorOptions="{rules: [{ required: true, message: '请选择仓库类型'}]}"
>
<a-select placeholder="请选择仓库类型">
<a-select-option value="公开">公开</a-select-option>
<a-select-option value="私密">私密</a-select-option>
</a-select>
</a-form-item>
</a-col>
</a-row>
<a-form-item v-if="showSubmit">
<a-button htmlType="submit" >Submit</a-button>
</a-form-item>
</a-form>
</template>
<script>
export default {
name: "RepositoryForm",
props: ['showSubmit'],
methods: {
handleSubmit (e) {
e.preventDefault()
this.form.validateFields((err, values) => {
if (!err) {
this.$notification['error']({
message: 'Received values of form:',
description: values
})
}
})
},
validate (rule, value, callback) {
const regex = /^user-(.*)$/
if (!regex.test(value)) {
callback('需要以 user- 开头')
}
callback()
}
}
}
</script>
<style scoped>
</style>
\ No newline at end of file
<template>
<a-form @submit="handleSubmit" :autoFormCreate="(form) => this.form = form" class="form">
<a-row class="form-row">
<a-col :lg="6" :md="12" :sm="24">
<a-form-item
label="任务名"
fieldDecoratorId="task.name"
:fieldDecoratorOptions="{rules: [{ required: true, message: '请输入任务名称', whitespace: true}]}"
>
<a-input placeholder="请输入任务名称" />
</a-form-item>
</a-col>
<a-col :xl="{span: 7, offset: 1}" :lg="{span: 8}" :md="{span: 12}" :sm="24">
<a-form-item
label="任务描述"
fieldDecoratorId="task.description"
:fieldDecoratorOptions="{rules: [{ required: true, message: '请输入任务描述', whitespace: true}]}"
>
<a-input placeholder="请输入任务描述"/>
</a-form-item>
</a-col>
<a-col :xl="{span: 9, offset: 1}" :lg="{span: 10}" :md="{span: 24}" :sm="24">
<a-form-item
label="执行人"
fieldDecoratorId="task.executor"
:fieldDecoratorOptions="{rules: [{ required: true, message: '请选择执行人'}]}"
>
<a-select placeholder="请选择执行人">
<a-select-option value="黄丽丽">黄丽丽</a-select-option>
<a-select-option value="李大刀">李大刀</a-select-option>
</a-select>
</a-form-item>
</a-col>
</a-row>
<a-row class="form-row">
<a-col :lg="6" :md="12" :sm="24">
<a-form-item
label="责任人"
fieldDecoratorId="task.manager"
:fieldDecoratorOptions="{rules: [{ required: true, message: '请选择责任人'}]}"
>
<a-select placeholder="请选择责任人">
<a-select-option value="王伟">王伟</a-select-option>
<a-select-option value="李红军">李红军</a-select-option>
</a-select>
</a-form-item>
</a-col>
<a-col :xl="{span: 7, offset: 1}" :lg="{span: 8}" :md="{span: 12}" :sm="24">
<a-form-item
label="提醒时间"
fieldDecoratorId="task.time"
:fieldDecoratorOptions="{rules: [{ required: true, message: '请选择提醒时间'}]}"
>
<a-time-picker style="width: 100%" />
</a-form-item>
</a-col>
<a-col :xl="{span: 9, offset: 1}" :lg="{span: 10}" :md="{span: 24}" :sm="24">
<a-form-item
label="任务类型"
fieldDecoratorId="task.type"
:fieldDecoratorOptions="{rules: [{ required: true, message: '请选择任务类型'}]}"
>
<a-select placeholder="请选择任务类型">
<a-select-option value="定时执行">定时执行</a-select-option>
<a-select-option value="周期执行">周期执行</a-select-option>
</a-select>
</a-form-item>
</a-col>
</a-row>
<a-form-item v-if="showSubmit">
<a-button htmlType="submit" >Submit</a-button>
</a-form-item>
</a-form>
</template>
<script>
export default {
name: "TaskForm",
props: ['showSubmit'],
methods: {
handleSubmit (e) {
e.preventDefault()
this.form.validateFields((err, values) => {
if (!err) {
this.$notification['error']({
message: 'Received values of form:',
description: values
})
}
})
}
}
}
</script>
<style scoped>
</style>
\ No newline at end of file
......@@ -6,6 +6,9 @@ module.exports = {
chunks: ['chunk-vendors', 'chunk-common', 'index']
}
},
configureWebpack: {
},
css: {
loaderOptions: {
less: {
......
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