兄弟们经过我上班摸鱼,最近摸了很多组件,一点点分享给大家。大佬们就别看了,二次封装很简单哦。我是根据element+封装的。大家在封装时,根据文档的api一步步实现。我给大家说说简单的思路。具体代码请看:https://gitee.com/liu--zicheng/vue3-vite-template/blob/master/src/components/ui/ZcForm.vue
其中也有table封装,包括搜索栏一键生成0。
<el-form-item label="Password" prop="pass">
<el-input v-model="ruleForm.pass" type="password" autocomplete="off" />
</el-form-item>
<el-form-item label="Confirm" prop="checkPass">
<el-input
v-model="ruleForm.checkPass"
type="password"
autocomplete="off"
/>
</el-form-item>
根据上面代码,大家来找相同的部分,然后通过配置的形式传入即可,是不是很简单。下面给大家分享我的配置文件。
import { formConfig } from "./../../../config/formConfig";
export const FormConfig = formConfig({
formItems: [
{
label: "表单1",
type: "number",
otherOptions: {
placeholder: "请输入账号",
},
prop: "account",
rules: [
{
required: true,
message: "请输入账号",
trigger: "change",
},
{
validator: (rule, value, callback) => {
console.log("....", typeof value);
if (value.length < 3 && value.length > 1) {
callback(new Error("请输入长度大于3"));
}
},
trigger: "change",
},
],
},
{
label: "表单2",
type: "password",
prop: "password",
otherOptions: {
placeholder: "请输入密码",
},
rules: [{ required: true, message: "请输入密码" }],
},
{
label: "表单3",
type: "datepicker",
otherOptions: {
startPlaceholder: "开始时间",
endPlaceholder: "结束时间",
type: "daterange",
"unlink-panels": true,
// disabled: true,
},
prop: "date",
rules: [{ required: true, message: "请选择日期" }],
},
{
label: "表单4",
type: "select",
otherOptions: {
placeholder: "请选择部门",
clearable: true,
multiple: true,
},
prop: "dep",
valueEnum: {
1: "部门1",
2: "部门2",
3: "部门3",
4: "部门4",
5: "部门5",
6: "部门6",
},
rules: [{ required: true, message: "请选择", trigger: "blur" }],
width: 100,
},
],
labelWidth: "100px",
// itemColLayout: {
// // span: 8,
// },
// itemStyle: {
// padding: "",
// },
});
这个配置文件,组件不需要动,除非有情况没有考虑,或者代码不严谨。大家可以根据情况书写自己的组件。
然后看看组件内部写法。
<template>
<el-form ref="ruleFormRef" :model="form" :label-width="labelWidth">
<el-row>
<template v-for="item in formItems">
<el-col v-bind="itemColLayout">
<el-form-item
:label="item.label"
:prop="item.prop"
:style="itemStyle"
:rules="item.rules"
>
<el-input
v-if="item.type == 'number'"
v-model="form[`${item.prop}`]"
:type="item.type"
v-bind="item.otherOptions"
onkeypress="return /[\d]/.test(String.fromCharCode(event.keyCode))"
/>
<el-input
v-if="item.type == 'input' || item.type == 'password'"
v-model="form[`${item.prop}`]"
:type="item.type"
:show-password="item.type === 'password'"
v-bind="item.otherOptions"
/>
<el-select
v-if="item.type == 'select'"
v-model="form[`${item.prop}`]"
v-bind="item.otherOptions"
style="width: 100%"
>
<el-option
v-for="option in item.valueEnum"
:key="option"
:label="item.valueEnum[option]"
:value="option"
></el-option>
</el-select>
<el-date-picker
v-if="item.type == 'datepicker'"
v-model="form[`${item.prop}`]"
v-bind="item.otherOptions"
></el-date-picker>
</el-form-item>
</el-col>
</template>
</el-row>
<div class="footer">
<slot name="footer">
<el-button type="primary" @click="resetBtnClick">重置</el-button>
<el-button type="primary" @click="searchBtnClick(ruleFormRef)"
>提交</el-button
>
</slot>
</div>
</el-form>
</template>
<script setup lang="ts">
import { RuleItem } from "async-validator";
import { FormInstance } from "element-plus";
import { StyleValue } from "vue";
const ruleFormRef = ref<FormInstance>();
interface FormItems {
label?: string;
type?: string;
placeholder?: string;
rules?: RuleItem;
prop?: string;
valueEnum?: Object;
clearable?: boolean;
disabled?: boolean;
multiple?: boolean;
width?: number;
otherOptions?: any;
}
const props = withDefaults(
defineProps<{
formItems: Array<FormItems | any>;
labelWidth?: string;
itemColLayout?: object;
itemStyle?: StyleValue;
request?: any;
}>(),
{
labelWidth: "120px",
itemColLayout: () => ({
xl: 6, // >=1920px
lg: 8, // >=1200px
md: 12, // >=992px
sm: 24, // >=768px
xs: 24, // <768px
}),
itemStyle: () => ({
padding: "0",
}),
}
);
const formParams = computed(() => {
let params: any = {};
props.formItems.map((item) => {
params[item.prop] = "";
});
return params;
});
const form = reactive({ ...formParams.value });
// 提交按钮
const searchBtnClick = async (formEl: FormInstance | undefined) => {
if (!formEl) return;
await formEl.validate((valid, fields) => {
if (valid) {
console.log("submit!", form);
props.request(form);
} else {
console.log("error submit!", valid, fields);
}
});
};
// 重置按钮
const resetBtnClick = () => {
ruleFormRef.value?.resetFields();
};
</script>
<style scoped lang="scss">
.footer {
text-align: right;
}
</style>