提交 73824607 编写于 作者: Mosher's avatar Mosher

add: 新增表单多数据部件(重复器)组件

上级 40fdac89
...@@ -147,6 +147,7 @@ import AppAddressCascader from './components/app-address-cascader/app-address-ca ...@@ -147,6 +147,7 @@ import AppAddressCascader from './components/app-address-cascader/app-address-ca
import AppInputIcon from './components/app-input-icon/app-input-icon.vue'; import AppInputIcon from './components/app-input-icon/app-input-icon.vue';
import AppTreeSelect from './components/app-tree-select/app-tree-select.vue' import AppTreeSelect from './components/app-tree-select/app-tree-select.vue'
import AppFormMdCtrl from './components/app-form-mdctrl/app-form-mdctrl.vue'; import AppFormMdCtrl from './components/app-form-mdctrl/app-form-mdctrl.vue';
import AppFormMdctrlRepeater from './components/app-form-mdctrl-repeater/app-form-mdctrl-repeater.vue';
// 全局挂载UI实体服务注册中心 // 全局挂载UI实体服务注册中心
window['uiServiceRegister'] = uiServiceRegister; window['uiServiceRegister'] = uiServiceRegister;
// 全局挂载实体权限服务注册中心 // 全局挂载实体权限服务注册中心
...@@ -308,5 +309,6 @@ export const AppComponents = { ...@@ -308,5 +309,6 @@ export const AppComponents = {
v.component('app-array-box', AppArrayBox); v.component('app-array-box', AppArrayBox);
v.component('app-tree-select', AppTreeSelect); v.component('app-tree-select', AppTreeSelect);
v.component('app-form-mdctrl', AppFormMdCtrl); v.component('app-form-mdctrl', AppFormMdCtrl);
v.component('app-form-mdctrl-repeater', AppFormMdctrlRepeater);
}, },
}; };
\ No newline at end of file
.app-form-mdctrl-repeater__row {
position: relative;
padding: 6px 0;
border-top: 1px dashed #eee;
&:first-child {
border-top: none;
}
}
.repeater-remove-default,
.repeater-remove-style2 {
display: none;
}
.el-table__row:hover {
.repeater-remove-style2 {
display: inline-block;
}
}
.repeater-remove-default {
position: absolute;
right: 0;
top: 2px;
z-index: 3;
}
.app-form-mdctrl-repeater__row:hover {
> .repeater-remove-default {
display: inline-block;
}
}
.app-form-mdctrl-repeater--style2 {
.repeater-add {
padding: 7px;
}
.app-form-mdctrl-repeater__header {
padding-bottom: 6px;
}
}
.repeater-caption {
padding-right: 20px;
font-weight: 600;
}
@index: 1, 2, 3, 4, 5;
each(@index, {
.app-form-mdctrl-repeater__level-@{value} > .app-form-mdctrl-repeater__header {
padding-left: @value * 20px;
}
})
.grid-column__localaction__remove {
display: none;
}
// 解决表格样式hover变化
.grid-column__localaction__content {
height: 28px;
}
.el-table__row:hover {
.grid-column__localaction__remove {
display: inline-block;
}
.grid-column__localaction__index {
display: none;
}
}
// .app-form-mdctrl-repeater--default {
// display: flex;
// flex-direction: column;
// }
<template>
<div :class="classNames">
<template v-if="mode === 'STYLE2'">
<div class="app-form-mdctrl-repeater__content">
<el-table :show-header="true" border :data="data">
<el-table-column
align="center"
class-name="grid-column__localaction"
width="64"
>
<template #header>
<el-button
type="primary"
class="repeater-add"
icon="el-icon-plus"
size="mini"
circle
@click="handleAdd"
></el-button>
</template>
<template #default="{ row, column, $index }">
<div class="repeater-grid-column">
<span class="grid-column__localaction__index">{{
$index + 1
}}</span>
<el-button
class="repeater-remove-style2"
type="danger"
size="mini"
icon="el-icon-delete"
circle
@click="handleRemove(row, $index)"
></el-button>
</div>
</template>
</el-table-column>
<el-table-column
:prop="key"
:align="columnAlign"
v-for="key of Object.keys(children)"
:key="key"
>
<template #header>
{{ children[key].caption }}
</template>
<template #default="{ row, column, $index }">
<slot
:name="key"
:data="row"
:context="context"
:viewparams="viewparams"
:onFormItemValueChange="
($event) => onFormItemValueChange($index, $event)
"
></slot>
</template>
</el-table-column>
</el-table>
</div>
</template>
<template v-else>
<div
class="app-form-mdctrl-repeater__header"
v-show="!(mode === 'STYLE3' && data.length >= 1)"
>
<span class="repeater-caption" v-if="showCaption && caption">{{
caption
}}</span>
<el-button
type="primary"
class="repeater-add"
icon="el-icon-plus"
size="mini"
circle
@click="handleAdd"
></el-button>
</div>
<div class="app-form-mdctrl-repeater__content">
<template v-for="(item, vIndex) of data">
<row class="app-form-mdctrl-repeater__row">
<el-button
class="repeater-remove-default"
type="danger"
size="mini"
circle
icon="el-icon-delete"
@click="handleRemove(item, vIndex)"
>
</el-button>
<slot
:context="context"
:viewparams="viewparams"
:data="item"
:onFormItemValueChange="
($event) => onFormItemValueChange(vIndex, $event)
"
></slot>
</row>
</template>
</div>
</template>
</div>
</template>
<script lang="ts">
import { Subject } from "rxjs";
import { Vue, Component, Prop, Model } from "vue-property-decorator";
@Component({})
export default class AppFormMdCtrlRepeater extends Vue {
/**
* 应用上下文
*
* @type {*}
* @memberof AppFormMdCtrlRepeater
*/
@Prop() public context: any;
/**
* 视图参数
*
* @type {*}
* @memberof AppFormMdCtrlRepeater
*/
@Prop() public viewparams: any;
/**
* 表单通讯状态
*
* @type {Subject<any>}
* @memberof AppFormMdCtrlRepeater
*/
@Prop() public formState!: Subject<any>;
/**
* 项名称
*
* @type {string}
* @memberof AppFormMdCtrlRepeater
*/
@Prop() public name!: string;
/**
* 层级
*
* @type {number}
* @memberof AppFormMdCtrlRepeater
*/
@Prop({ default: 0 }) public level?: number;
/**
* 数据
*
* @type {any[]}
* @memberof AppFormMdCtrlRepeater
*/
@Model() public data!: any[];
/**
* 模式
*
* @type {string}
* @memberof AppFormMdCtrlRepeater
*/
@Prop({ default: "DEFAULT" }) public mode?:
| "DEFAULT"
| "STYLE2"
| "STYLE3"
| string;
/**
* 是否显示标题
*
* @type {boolean}
* @memberof AppFormMdCtrlRepeater
*/
@Prop({ default: true }) public showCaption?: boolean;
/**
* 标题
*
* @type {string}
* @memberof AppFormMdCtrlRepeater
*/
@Prop() public caption!: string;
/**
* 子集合
*
* @type {*}
* @memberof AppFormMdCtrlRepeater
*/
@Prop({
default: () => {
return {};
},
})
public children: any;
/**
* 应用上下文
*
* @type {"center" | "left" | "right"}
* @memberof AppFormMdCtrlRepeater
*/
@Prop({ default: "center" }) public columnAlign?: "center" | "left" | "right";
/**
* 样式表
*
* @type {*}
* @memberof AppFormMdCtrlRepeater
*/
get classNames() {
return {
"app-form-mdctrl-repeater": true,
[`app-form-mdctrl-repeater--${this.name.toLowerCase()}`]: true,
[`app-form-mdctrl-repeater--${(this.mode || "DEFAULT").toLowerCase()}`]:
true,
[`app-form-mdctrl-repeater__level-${this.level}`]: true,
};
}
/**
* 处理数据增加
*
* @memberof AppFormMdCtrlRepeater
*/
public handleAdd() {
const item = {};
Object.keys(this.children).forEach((key: string) => {
Object.assign(item, {
[key]: this.children[key].type === "MDCTRL" ? [] : null,
});
});
if (!this.data) {
this.data = [];
}
if (this.mode === "STYLE2") {
this.data.unshift(item);
} else {
this.data.push(item);
}
}
/**
* 处理数据删除
*
* @memberof AppFormMdCtrlRepeater
*/
public handleRemove(data: any, index: number) {
this.data.splice(index, 1);
}
/**
* 处理数据项变化
*
* @memberof AppFormMdCtrlRepeater
*/
public onFormItemValueChange(
index: number,
{ name, value }: { name: string; value: any }
) {
if (!name) {
return;
}
this.data[index][name] = value;
}
}
</script>
<style lang="less">
@import "./app-form-mdctrl-repeater.less";
</style>
Markdown 格式
0% or
您添加了 0 到此讨论。请谨慎行事。
先完成此消息的编辑!
想要评论请 注册