style: 删除无用组件

This commit is contained in:
rd
2025-07-25 17:37:51 +08:00
parent 3d08f9c8d3
commit 077d45e58b
13 changed files with 0 additions and 1053 deletions

View File

@ -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>

View File

@ -1,5 +0,0 @@
# 动态配置form表单
示例见 views/components/form
参数 fieldList配置项包括arco.design Form.Item和Input、Select以及自定义属性component等
参数 model: 传默认值
通过ref获取实例调用子组件实例updateFieldsList方法更新配置项调用setModel方法更新数据调用setForm方法更新Form属性自定义事件change处理逻辑

View File

@ -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,
};

View File

@ -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>

View File

@ -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;
}
}

View File

@ -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;
};

View File

@ -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>