style: 删除无用组件
This commit is contained in:
@ -1,70 +0,0 @@
|
||||
<!--
|
||||
* @Author: 田鑫
|
||||
* @Date: 2023-02-16 11:58:01
|
||||
* @LastEditors: 田鑫
|
||||
* @LastEditTime: 2023-02-16 16:56:27
|
||||
* @Description: 二次确认框
|
||||
-->
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<a-popconfirm
|
||||
:content="content"
|
||||
:position="position"
|
||||
:ok-text="okText"
|
||||
:cancel-text="cancelText"
|
||||
:type="popupType"
|
||||
@ok="handleConfirm"
|
||||
@cancel="handleCancel"
|
||||
>
|
||||
<slot></slot>
|
||||
</a-popconfirm>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { PropType } from 'vue-demi';
|
||||
|
||||
type Position = 'top' | 'tl' | 'tr' | 'bottom' | 'bl' | 'br' | 'left' | 'lt' | 'lb' | 'right' | 'rt' | 'rb';
|
||||
|
||||
type PopupType = 'info' | 'success' | 'warning' | 'error';
|
||||
|
||||
const props = defineProps({
|
||||
content: {
|
||||
type: String,
|
||||
default: '是否确认?',
|
||||
},
|
||||
position: {
|
||||
type: String as PropType<Position>,
|
||||
default: 'top',
|
||||
},
|
||||
okText: {
|
||||
type: String,
|
||||
default: '确定',
|
||||
},
|
||||
cancelText: {
|
||||
type: String,
|
||||
default: '取消',
|
||||
},
|
||||
popupType: {
|
||||
type: String as PropType<PopupType>,
|
||||
default: 'info',
|
||||
},
|
||||
});
|
||||
|
||||
const emit = defineEmits(['confirmEmit', 'cancelEmit']);
|
||||
|
||||
/**
|
||||
* 确定事件
|
||||
*/
|
||||
function handleConfirm() {
|
||||
emit('confirmEmit');
|
||||
}
|
||||
/**
|
||||
* 确定事件
|
||||
*/
|
||||
function handleCancel() {
|
||||
emit('cancelEmit');
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped></style>
|
||||
@ -1,5 +0,0 @@
|
||||
# 动态配置form表单
|
||||
示例见 views/components/form
|
||||
参数 fieldList:配置项,包括arco.design Form.Item和Input、Select以及自定义属性component等
|
||||
参数 model: 传默认值
|
||||
通过ref获取实例,调用子组件实例updateFieldsList方法更新配置项,调用setModel方法更新数据,调用setForm方法更新Form属性,自定义事件change处理逻辑
|
||||
@ -1,40 +0,0 @@
|
||||
// form.item的属性名称集合
|
||||
export const formItemKeys = [
|
||||
'field',
|
||||
'label',
|
||||
'tooltip',
|
||||
'showColon',
|
||||
'noStyle',
|
||||
'disabled',
|
||||
'help',
|
||||
'extra',
|
||||
'required',
|
||||
'asteriskPosition',
|
||||
'rules',
|
||||
'validateStatus',
|
||||
'validateTrigger',
|
||||
'wrapperColProps',
|
||||
'hideLabel',
|
||||
'hideAsterisk',
|
||||
'labelColStyle',
|
||||
'wrapperColStyle',
|
||||
'rowProps',
|
||||
'rowClass',
|
||||
'contentClass',
|
||||
'contentFlex',
|
||||
'labelColFlex',
|
||||
'feedback',
|
||||
'labelComponent',
|
||||
'labelAttrs',
|
||||
];
|
||||
// 自定义属性名称集合
|
||||
export const customKeys = ['component', 'lists'];
|
||||
// 响应式栅格默认配置
|
||||
export const COL_PROPS = {
|
||||
xs: 12,
|
||||
sm: 12,
|
||||
md: 8,
|
||||
lg: 8,
|
||||
xl: 6,
|
||||
xxl: 6,
|
||||
};
|
||||
@ -1,271 +0,0 @@
|
||||
<template>
|
||||
<slot name="header"></slot>
|
||||
<a-form v-bind="_options" ref="formRef" :model="model" @submit.prevent>
|
||||
<a-row v-bind="rowProps" :gutter="20">
|
||||
<template
|
||||
v-for="{ field, component, formItemProps, componentProps, lists, colProps } in newFieldList"
|
||||
:key="field"
|
||||
>
|
||||
<!-- 单选框 -->
|
||||
<a-col v-if="component === 'radio'" v-bind="colProps">
|
||||
<a-form-item v-bind="formItemProps">
|
||||
<a-radio-group v-bind="componentProps" v-model="model[field]">
|
||||
<a-radio v-for="val in lists" :key="val['value']" :label="val['value']" size="large">
|
||||
{{ val['label'] }}
|
||||
</a-radio>
|
||||
</a-radio-group>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<!-- 复选框 -->
|
||||
<a-col v-if="component === 'checkbox'" v-bind="colProps">
|
||||
<a-form-item v-bind="formItemProps">
|
||||
<a-checkbox-group v-bind="componentProps" v-model="model[field]">
|
||||
<a-checkbox v-for="c in lists" :key="c['value']" :label="c['value']">{{ c['label'] }}</a-checkbox>
|
||||
</a-checkbox-group>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<!-- 下拉框 -->
|
||||
<a-col v-if="component === 'select'" v-bind="colProps">
|
||||
<a-form-item v-bind="formItemProps">
|
||||
<a-select v-bind="componentProps" v-model="model[field]">
|
||||
<a-option v-for="s in lists" :key="s['value']" :label="s['label']" :value="s['value']" />
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<!-- 文本域 -->
|
||||
<a-col v-if="component === 'textarea'" v-bind="colProps">
|
||||
<a-form-item v-bind="formItemProps">
|
||||
<a-textarea v-bind="componentProps" v-model="model[field]" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<!-- 时间选择器 -->
|
||||
<a-col v-if="component === 'time'" v-bind="colProps">
|
||||
<a-form-item v-bind="formItemProps">
|
||||
<a-time-picker v-bind="componentProps" v-model="model[field]" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<!-- 日期选择器 -->
|
||||
<a-col v-if="component === 'date'" v-bind="colProps">
|
||||
<a-form-item v-bind="formItemProps">
|
||||
<a-date-picker v-bind="componentProps" v-model="model[field]" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<!-- 日期范围选择器 -->
|
||||
<a-col v-if="component === 'rangeDate'" v-bind="colProps">
|
||||
<a-form-item v-bind="formItemProps">
|
||||
<a-range-picker v-bind="componentProps" v-model="model[field]" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<!-- 级联选择器 -->
|
||||
<a-col v-if="component === 'cascader'" v-bind="colProps">
|
||||
<a-form-item v-bind="formItemProps">
|
||||
<a-cascader v-bind="componentProps" v-model="model[field]" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<!-- 数字输入框 -->
|
||||
<a-col v-if="component === 'inputNumber'" v-bind="colProps">
|
||||
<a-form-item v-bind="formItemProps">
|
||||
<a-input-number v-bind="componentProps" v-model="model[field]" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<!-- 输入框 -->
|
||||
<a-col v-if="component === 'input'" v-bind="colProps">
|
||||
<a-form-item v-bind="formItemProps">
|
||||
<a-input v-bind="componentProps" v-model="model[field]" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<!-- 标题模块 -->
|
||||
<a-col v-if="component === 'title'" :span="24">
|
||||
<div class="title">
|
||||
<div class="bar"></div>
|
||||
<h4 class="text">{{ formItemProps.label }}</h4>
|
||||
</div>
|
||||
</a-col>
|
||||
<!-- 自定义插槽slot -->
|
||||
<a-col v-if="component === 'slot'" :span="24">
|
||||
<slot :name="field"></slot>
|
||||
</a-col>
|
||||
</template>
|
||||
<a-col :span="24">
|
||||
<a-form-item>
|
||||
<slot name="buttons" :model="model" :formRef="formRef">
|
||||
<a-space>
|
||||
<a-button type="primary" @click="onSubmit(formRef)">{{ _options.submitButtonText }}</a-button>
|
||||
<a-button v-if="_options.showResetButton" @click="resetForm(formRef)">
|
||||
{{ _options.resetButtonText }}
|
||||
</a-button>
|
||||
<a-button v-if="_options.showCancelButton" @click="emit('cancel')">
|
||||
{{ _options.cancelButtonText }}
|
||||
</a-button>
|
||||
</a-space>
|
||||
</slot>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-form>
|
||||
<slot name="footer"></slot>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import type { FormInstance, RowProps, ValidatedError } from '@arco-design/web-vue';
|
||||
import type { ComputedRef } from 'vue';
|
||||
import type { Form } from './interface';
|
||||
import { formItemKeys, customKeys, COL_PROPS } from './constants';
|
||||
import { changeFormList } from './utils';
|
||||
import type { FieldData } from '@arco-design/web-vue/es/form/interface';
|
||||
// 父组件传递的值
|
||||
interface Props {
|
||||
fieldList: Form.FieldItem[];
|
||||
model?: Record<string, any>;
|
||||
options?: Form.Options;
|
||||
rowProps?: RowProps;
|
||||
}
|
||||
interface EmitEvent {
|
||||
(e: 'submit' | 'change', params: any): void;
|
||||
(e: 'reset' | 'cancel'): void;
|
||||
}
|
||||
|
||||
const props = defineProps<Props>();
|
||||
const emit = defineEmits<EmitEvent>();
|
||||
// 表单的数据
|
||||
let model = ref<Record<string, any>>({});
|
||||
|
||||
const formRef = ref<FormInstance>();
|
||||
|
||||
// 初始化处理Form组件属性options
|
||||
const _options = ref<Record<string, any>>({});
|
||||
const initOptions = () => {
|
||||
const option = {
|
||||
layout: 'vertical',
|
||||
disabled: false,
|
||||
submitButtonText: '提交',
|
||||
resetButtonText: '重置',
|
||||
cancelButtonText: '取消',
|
||||
showResetButton: true,
|
||||
};
|
||||
Object.assign(option, props?.options);
|
||||
_options.value = option;
|
||||
};
|
||||
initOptions();
|
||||
// 初始化处理model
|
||||
const initFormModel = () => {
|
||||
props.fieldList.forEach((item: Form.FieldItem) => {
|
||||
// 如果类型为checkbox,默认值需要设置一个空数组
|
||||
const value = item.component === 'checkbox' ? [] : '';
|
||||
const { field, component } = item;
|
||||
if (component !== 'slot' && component !== 'title') {
|
||||
model.value[item.field] = props?.model?.[field] || value;
|
||||
}
|
||||
});
|
||||
};
|
||||
initFormModel();
|
||||
// 初始化处理fieldList
|
||||
const newFieldList: any = ref(null);
|
||||
const initFieldList = () => {
|
||||
const list = props?.fieldList.map((item: Form.FieldItem) => {
|
||||
const customProps = pick(item, customKeys);
|
||||
const formItemProps = pick(item, formItemKeys);
|
||||
const componentProps = omit(item, [...formItemKeys, ...customKeys, 'field', 'colProps']);
|
||||
const { colProps = {}, field, placeholder, component = 'input', label } = item;
|
||||
componentProps.onChange = (val: any) => onChange(field, val);
|
||||
const newColProps = {
|
||||
...colProps,
|
||||
...COL_PROPS,
|
||||
};
|
||||
const obj = {
|
||||
field,
|
||||
colProps: newColProps,
|
||||
...customProps,
|
||||
formItemProps,
|
||||
componentProps,
|
||||
};
|
||||
if ((component === 'input' || component === 'textarea') && !placeholder) {
|
||||
componentProps.placeholder = `请输入${label}`;
|
||||
}
|
||||
if (component === 'select' && !placeholder) {
|
||||
componentProps.placeholder = `请选择${label}`;
|
||||
}
|
||||
if (component === 'rangeDate') {
|
||||
componentProps.value = [null, null];
|
||||
}
|
||||
return obj;
|
||||
});
|
||||
newFieldList.value = list;
|
||||
return list;
|
||||
};
|
||||
initFieldList();
|
||||
// 提交
|
||||
const onSubmit = async (formEl: FormInstance | undefined) => {
|
||||
if (!formEl) return;
|
||||
let flag = false;
|
||||
await formEl.validate((errors: undefined | Record<string, ValidatedError>) => {
|
||||
if (!errors) {
|
||||
emit('submit', model.value);
|
||||
flag = true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
return (flag && model.value) || null;
|
||||
};
|
||||
// 提交--父组件调用
|
||||
const submit = () => {
|
||||
return onSubmit(formRef.value);
|
||||
};
|
||||
// 重置
|
||||
const resetForm = (formEl: FormInstance | undefined) => {
|
||||
if (!formEl) return;
|
||||
formEl.resetFields();
|
||||
};
|
||||
// 表单变化
|
||||
const onChange = (key: string, val: any) => {
|
||||
emit('change', { key, val });
|
||||
};
|
||||
// 设置
|
||||
const setModel = (data: Record<string, FieldData>) => {
|
||||
const newData = {
|
||||
...model.value,
|
||||
...data,
|
||||
};
|
||||
model.value = newData;
|
||||
};
|
||||
// 设置Form
|
||||
const setForm = (data: Form.Options) => {
|
||||
const options = {
|
||||
..._options.value,
|
||||
...data,
|
||||
};
|
||||
_options.value = options;
|
||||
};
|
||||
// 更新配置项
|
||||
const updateFieldsList = (updateList: any[]) => {
|
||||
const list = changeFormList(newFieldList.value, updateList);
|
||||
newFieldList.value = list;
|
||||
};
|
||||
|
||||
defineExpose({
|
||||
submit,
|
||||
setModel,
|
||||
setForm,
|
||||
updateFieldsList,
|
||||
});
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
:deep(.arco-picker) {
|
||||
width: 100%;
|
||||
}
|
||||
.title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
.bar {
|
||||
width: 4px;
|
||||
height: 14px;
|
||||
border-radius: 1px;
|
||||
margin-right: 8px;
|
||||
background-color: rgb(var(--primary-6));
|
||||
}
|
||||
.text {
|
||||
font-size: 16px;
|
||||
color: var(--color-text-1);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
95
src/components/wyg-form/interface.d.ts
vendored
95
src/components/wyg-form/interface.d.ts
vendored
@ -1,95 +0,0 @@
|
||||
import type { FieldRule } from '@arco-design/web-vue/es/form/interface';
|
||||
import { Size, ColProps, CascaderOption, InputProps } from '@arco-design/web-vue';
|
||||
console.log(InputProps, 'InputProps=====');
|
||||
|
||||
export namespace Form {
|
||||
/** 表单项自身Props */
|
||||
interface FormItem<T = string> {
|
||||
field: string;
|
||||
label: string;
|
||||
tooltip?: string;
|
||||
showColon?: boolean;
|
||||
noStyle?: boolean;
|
||||
disabled?: boolean;
|
||||
help?: string;
|
||||
extra?: string;
|
||||
required?: boolean;
|
||||
asteriskPosition?: 'start' | 'end';
|
||||
rules?: FieldRule | FieldRule[];
|
||||
validateStatus?: 'success' | 'warning' | 'error' | 'validating';
|
||||
validateTrigger?: 'change' | 'input' | 'focus' | 'blur';
|
||||
labelColProps?: object;
|
||||
wrapperColProps?: object;
|
||||
hideLabel?: boolean;
|
||||
hideAsterisk?: boolean;
|
||||
labelColStyle?: object;
|
||||
wrapperColStyle?: object;
|
||||
rowProps?: object;
|
||||
rowClass?: string | Array<T> | object;
|
||||
contentClass?: string | Array<T> | object;
|
||||
contentFlex?: boolean;
|
||||
labelColFlex?: number | string;
|
||||
feedback?: boolean;
|
||||
labelComponent?: string;
|
||||
labelAttrs?: object;
|
||||
}
|
||||
// 当前 fieldItem 的类型 默认值'input'
|
||||
type ComponentType =
|
||||
| 'input'
|
||||
| 'textarea'
|
||||
| 'radio'
|
||||
| 'checkbox'
|
||||
| 'select'
|
||||
| 'time'
|
||||
| 'date'
|
||||
| 'rangeDate'
|
||||
| 'inputNumber'
|
||||
| 'cascader'
|
||||
| 'title'
|
||||
| 'slot';
|
||||
/** 自定义Props */
|
||||
interface CustomProps {
|
||||
component?: ComponentType;
|
||||
lists?: object; // 如果 type='checkbox' / 'radio' / 'select'时,需传入此配置项。格式参考FieldItemOptions配置项
|
||||
}
|
||||
/** Input、Select组件等的Props */
|
||||
interface ComponentProps {
|
||||
placeholder?: string; // 输入框占位文本
|
||||
readonly?: boolean; // 是否只读 false
|
||||
allowClear?: boolean; // 是否可清空 false
|
||||
onChange?: Function;
|
||||
options?: CascaderOption[];
|
||||
}
|
||||
/** 每一项配置项的属性 */
|
||||
interface FieldItem extends FormItem, CustomProps, ComponentProps {
|
||||
colProps?: ColProps;
|
||||
}
|
||||
/** 处理后的配置项属性 */
|
||||
interface NewFieldItem extends CustomProps {
|
||||
formItemProps: FormItem;
|
||||
componentProps: ComponentProps;
|
||||
field: string;
|
||||
colProps?: ColProps;
|
||||
}
|
||||
interface FieldItemOptions {
|
||||
label: string | number;
|
||||
value: string | number;
|
||||
}
|
||||
/** 表单Form自身Props */
|
||||
interface Options {
|
||||
layout?: 'horizontal' | 'vertical' | 'inline'; // 表单的布局方式,包括水平、垂直、多列
|
||||
size?: Size; // 用于控制该表单内组件的尺寸
|
||||
labelColProps?: object; // 标签元素布局选项。参数同 <col> 组件一致,默认值span: 5, offset: 0
|
||||
wrapperColProps?: object; // 表单控件布局选项。参数同 <col> 组件一致,默认值span: 19, offset: 0
|
||||
labelAlign?: 'left' | 'right'; // 标签的对齐方向,默认值'right'
|
||||
disabled?: boolean; // 是否禁用表单
|
||||
rules?: Record<string, FieldRule | FieldRule[]>; // 表单项校验规则
|
||||
autoLabelWidth?: boolean; // 是否开启自动标签宽度,仅在 layout="horizontal" 下生效。默认值false
|
||||
|
||||
showResetButton?: boolean; // 是否展示重置按钮
|
||||
showCancelButton?: boolean; // 是否展示取消按钮
|
||||
submitButtonText?: string;
|
||||
resetButtonText?: string;
|
||||
cancelButtonText?: string;
|
||||
}
|
||||
}
|
||||
@ -1,25 +0,0 @@
|
||||
import { formItemKeys, customKeys, COL_PROPS } from './constants';
|
||||
import type { Form } from './interface';
|
||||
// fieldList更新
|
||||
export const changeFormList = (formList: Form.NewFieldItem[], updateList: Form.FieldItem[]): Form.NewFieldItem[] => {
|
||||
let list: any = formList;
|
||||
list.forEach((item: any, index: string | number) => {
|
||||
updateList.forEach((ele: any) => {
|
||||
if (item.field === ele.field) {
|
||||
list[index] = { ...item, ...ele };
|
||||
const keys: string[] = Object.keys(ele);
|
||||
keys.forEach((key: string) => {
|
||||
const val = ele[key];
|
||||
if (formItemKeys.includes(key)) {
|
||||
list[index].formItemProps[key] = val;
|
||||
} else if (customKeys.includes(key) || key === 'colProps') {
|
||||
list[index][key] = val;
|
||||
} else {
|
||||
list[index].componentProps[key] = val;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
return list;
|
||||
};
|
||||
@ -1,73 +0,0 @@
|
||||
<!--
|
||||
* @Author: 田鑫
|
||||
* @Date: 2023-02-16 14:40:38
|
||||
* @LastEditors: 田鑫
|
||||
* @LastEditTime: 2023-02-16 16:37:52
|
||||
* @Description: table公用封装
|
||||
-->
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<a-table
|
||||
:loading="loading"
|
||||
:size="size"
|
||||
:data="tableData"
|
||||
:bordered="{ cell: borderCell }"
|
||||
:pagination="setPagination"
|
||||
page-position="br"
|
||||
v-bind="propsRes"
|
||||
v-on="propsEvent"
|
||||
>
|
||||
<template #columns>
|
||||
<slot></slot>
|
||||
</template>
|
||||
</a-table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { PaginationProps, TableData } from '@arco-design/web-vue';
|
||||
import type { PropType } from 'vue-demi';
|
||||
import Components from 'unplugin-vue-components/vite';
|
||||
|
||||
type Size = 'mini' | 'small' | 'medium' | 'large';
|
||||
|
||||
const props = defineProps({
|
||||
size: {
|
||||
type: String as PropType<Size>,
|
||||
default: 'large',
|
||||
},
|
||||
tableData: {
|
||||
type: Array as PropType<TableData[]>,
|
||||
default: () => [],
|
||||
},
|
||||
borderCell: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
pagination: {
|
||||
type: Object as PropType<PaginationProps>,
|
||||
default: () => {},
|
||||
},
|
||||
});
|
||||
const loading = ref(false);
|
||||
|
||||
const setPagination = computed(() => {
|
||||
const defaultPagination: PaginationProps = {
|
||||
showPageSize: true,
|
||||
showTotal: true,
|
||||
showMore: true,
|
||||
size: 'large',
|
||||
};
|
||||
return Object.assign(defaultPagination, props.pagination);
|
||||
});
|
||||
|
||||
watchEffect(() => {
|
||||
if (props.tableData.length === 0) {
|
||||
loading.value = true;
|
||||
} else {
|
||||
loading.value = false;
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<style lang="scss" scoped></style>
|
||||
Reference in New Issue
Block a user