<template>
<el-row :gutter="$attrs.gutter">
{{ formData }}
<el-form
v-bind="$attrs"
v-on="$listeners"
:label-width="$attrs.labelWidth || '140px'"
>
<template v-for="item in formHeader">
<el-col
:key="item.prop"
v-if="!item.hidden"
:span="item.span || allSpan"
:class="item.right ? 'flexAlignCenterRight' : ''"
>
<el-form-item
v-bind="item"
:rules="
item.required
? [
{
required: true,
message: `${item.label.replace(/(.*?)/g, '')}必填`,
trigger: 'blur',
},
]
: null
"
v-required="
item.dir === true || (item.required && item.dir !== false)
? formData[item.prop]
: '1'
"
>
<!-- 渲染函数 -->
<template v-if="item.render">
<ex-slot :render="item.render" :row="formData" />
</template>
<!-- 上传 -->
<template v-else-if="item.type === 'upload'">
<el-upload
ref="upload"
style=" 200px"
:file-list="field101fileList"
:action="field101Action"
:multiple="item.multiple || false"
:before-upload="field101BeforeUpload"
:accept="item.accept || '*'"
:disabled="item.disabled || false"
>
<el-button size="small" type="primary" icon="el-icon-upload"
>点击上传</el-button
>
<div slot="tip" class="el-upload__tip">
{{ item.upload__tip }}
</div>
</el-upload>
</template>
<!-- 日期范围选择器 -->
<template v-else-if="item.type === 'daterange'">
<el-date-picker
type="daterange"
v-model="formData[item.prop]"
v-bind="item"
:format="item.format || 'yyyy-MM-dd'"
:value-format="item.valueFormat || 'yyyy-MM-dd'"
:start-placeholder="item.startPlaceholder || '开始日期'"
:end-placeholder="item.endPlaceholder || '结束日期'"
:range-separator="item.rangeSeparator || '至'"
></el-date-picker>
</template>
<!-- 日期选择器 -->
<template v-else-if="item.type === 'date'">
<el-date-picker
v-model="formData[item.prop]"
:format="item.format || 'yyyy-MM-dd'"
:value-format="item.valueFormat || 'yyyy-MM-dd'"
v-bind="item"
></el-date-picker>
</template>
<!-- 时间选择器 -->
<template v-else-if="item.type === 'timerange'">
<el-time-picker
v-model="formData[item.prop]"
v-bind="item"
is-range
:format="item.format || 'HH:mm:ss'"
:value-format="item.valueFormat || 'HH:mm:ss'"
:start-placeholder="item.startPlaceholder || '开始时间'"
:end-placeholder="item.endPlaceholder || '结束时间'"
:range-separator="item.rangeSeparator || '至'"
></el-time-picker>
</template>
<!-- 时间选择器 -->
<template v-else-if="item.type === 'time'">
<el-time-picker
v-model="formData[item.prop]"
:format="item.format || 'HH:mm:ss'"
:value-format="item.valueFormat || 'HH:mm:ss'"
:picker-options="{ selectableRange: '00:00:00-23:59:59' }"
v-bind="item"
></el-time-picker>
</template>
<!-- 下拉 -->
<template v-else-if="item.type === 'select'">
<el-select
v-model="formData[item.prop]"
v-bind="item"
:multiple="item.multiple || false"
:filterable="item.filterable || true"
:disabled="item.disabled || false"
>
<el-option
v-for="(el, i) in item.options"
:key="i"
:label="el.label"
:value="el.value"
:disabled="el.disabled"
>
</el-option>
</el-select>
</template>
<!-- 单选 -->
<template v-else-if="item.type === 'radio'">
<el-radio-group
v-model="formData[item.prop]"
v-bind="item"
:disabled="item.disabled || false"
>
<el-radio
v-for="(el, i) in item.options"
:key="i"
:label="el.value"
:disabled="el.disabled"
:border="el.border"
>
{{ el.label }}
</el-radio>
</el-radio-group>
</template>
<!-- 滑块 -->
<template v-else-if="item.type === 'switch'">
<el-switch
style=" 200px"
v-model="formData[item.prop]"
:active-text="item.activeText"
:inactive-text="item.inactiveText"
:active-color="item.activeColor ? item.activeColor : '#13ce66'"
:inactive-color="
item.inactiveColor ? item.inactiveColor : '#ff4949'
"
:disabled="item.disabled || false"
></el-switch>
</template>
<!-- 多选 -->
<template v-else-if="item.type === 'checkbox'">
<el-checkbox-group
v-model="formData[item.prop]"
v-bind="item"
:disabled="item.disabled || false"
:min="item.min"
:max="item.max"
>
<el-checkbox
v-for="(el, i) in item.options"
:key="i"
:label="el.value"
:disabled="el.disabled"
:border="el.border"
>
{{ el.label }}
</el-checkbox>
</el-checkbox-group>
</template>
<!-- 输入型 -->
<!-- 多行 考虑加入富文本-->
<template v-else-if="item.type === 'textarea'">
<el-input
type="textarea"
v-model.trim="formData[item.prop]"
v-bind="item"
>
<template slot="prepend" v-if="item.prepend">{{
item.prepend
}}</template>
<template slot="append" v-if="item.append">{{
item.append
}}</template>
</el-input>
</template>
<!-- 计数 -->
<template
v-else-if="item.type === 'number' || item.type === 'price'"
>
<!-- {{item}}v-model.trim="formData[item.prop]" -->
<!-- <el-input
:value="formatterValue(item)"
@input="change($event,item)"
@change="change($event,item)"
></el-input> -->
<el-input-number
v-model.trim="formData[item.prop]"
:controls="item.controls || false"
:step="item.step || 0.01"
v-bind="commonProp(item)"
:min="
item.min !== null && item.min !== undefined ? item.min : 0.0
"
:precision="
item.precision !== null && item.precision !== undefined
? item.precision
: 2
"
:max="
item.max !== null && item.max !== undefined
? item.max
: 100000000
"
:step-strictly="item.stepStrictly || true"
></el-input-number>
</template>
<!-- 单行 -->
<template v-else>
<el-input
v-model.trim="formData[item.prop]"
v-bind="item"
:prefix-icon="item.prefixIcon"
:suffix-icon="item.suffixIcon"
style=" 200px"
>
<template slot="prepend" v-if="item.prepend">{{
item.prepend
}}</template>
<template slot="append" v-if="item.append">{{
item.append
}}</template>
</el-input>
</template>
</el-form-item>
</el-col>
</template>
</el-form>
</el-row>
</template>
<script>
// 自定义内容的组件
let exSlot = {
functional: true,
props: {
row: Object,
render: Function,
},
render: (h, data) => {
const params = {
row: data.props.row,
};
return data.props.render(h, params);
},
};
export default {
name: "form-default",
inheritAttrs: false,
components: { exSlot },
props: {
//所有col统一栅格
allSpan: {
type: Number,
default: 12,
},
//所有控件统一宽度
allWidth: {
type: [String, Number],
default: "200px",
},
formData: {
type: Object,
default: function () {
return {};
},
},
// 表头数据
formHeader: {
type: Array,
default: function () {
return [];
},
},
},
computed: {
// formatterValue(e) {
// // if (this.formatter && this.precisionValue !== null) {
// // return this.formatter(this.precisionValue);
// // } else {
// // return this.precisionValue;
// // }
// console.log(e.target);
// // return 55
// },
},
data() {
return {
field101Action: "https://jsonplaceholder.typicode.com/posts/",
field101Action: "#",
field101fileList: [],
};
},
// computed: {
// comHeader() {
// return this.formHeader;
// },
// },
created() {
this.formHeader.forEach((item) => {
if (
item.format === "array" &&
Object.prototype.toString.call(this.formData[item.prop]) !==
"[object Array]"
) {
this.$set(this.formData, item.prop, []);
}
});
},
methods: {
formatterValue(item){
if(item.formatter){
return item.formatter(this.formData[item.prop])
}else{
return this.formData[item.prop]
}
// console.log(item.formatter(50000));
// console.log(this.change);
// return item.formatter(this.formData[item.prop])
},
change(event,item) {
if(item.parser){
this.formData[item.prop]=item.parser(event)
}else{
this.formData[item.prop]=event
}
},
validate() {
return this.$refs.elForm.validate();
},
clearValidate() {
this.$refs.elForm.clearValidate();
},
proppath(row, path) {
let arr = path.split(".");
let a = row;
arr.forEach((item) => {
a = a[item];
});
return a;
},
field101BeforeUpload(file) {
let isRightSize = file.size / 1024 / 1024 < 2;
if (!isRightSize) {
this.$message.error("文件大小超过 2MB");
}
console.log(file.type);
let isAccept = new RegExp("application").test(file.type);
if (isAccept) {
this.$message.error("应该选择非.exe等类型的文件");
}
return isRightSize && isAccept;
},
},
};
</script>
<style lang="scss" scoped>
::v-deep .el-input-number .el-input__inner {
text-align: left;
}
</style>
<template>
<FormDefault
:formData="info"
:formHeader="defaultHeader"
:rules="rules"
class="mt10"
ref="elForm"
:model="info"
size="mini"
></FormDefault>
</template>
<script>
import FormDefault from "./form.vue";
export default {
components: { FormDefault },
data() {
return {
info: {
f1: 12,
},
rules: {
f1: [{ required: true }],
},
defaultHeader: [
{
prop: "f0",
label: "评测预算费(元)",
placeholder: "请输5入金额",
type: "upload",
required: true,
render: (h, params) => {
return [<div>4545</div>];
},
},
{
prop: "f1",
label: "评测预算费(元)",
placeholder: "请输5入金额",
type: "number",
formatter: (value) =>
`${value}`.replace(/B(?=(d{3})+(?!d))/g, ","),
parser: (value) => `${value}`.replace(/$s?|(,*)/g, ""),
required: true,
},
{
prop: "f2",
label: "研发预算费(元)",
placeholder: "请输入金额",
type: "daterange",
},
{
prop: "f3",
label: "专利预算费(元)",
placeholder: "请输入金额",
type: "date",
},
{
prop: "f4",
label: "专家验收预算费(元)",
placeholder: "请输入金额",
type: "timerange",
},
{
prop: "f53",
label: "采购预算费(元)",
placeholder: "请输入金额",
type: "time",
},
{
prop: "f54",
label: "实施预算费(元))",
placeholder: "请输入金额",
type: "select",
multiple: true,
options: [
{
value: "选项1",
label: "黄金糕",
},
{
value: "选项2",
label: "双皮奶",
},
{
value: "选项3",
label: "蚵仔煎",
},
],
},
{
prop: "f5",
label: "其他预算费(元)",
placeholder: "请输入金额",
type: "radio",
options: [
{
value: "选项1",
label: "黄金糕",
},
{
value: "选项2",
label: "双皮奶",
},
{
value: "选项3",
label: "蚵仔煎",
},
],
},
{
prop: "f6",
label: "论文预算费(元)",
placeholder: "请输入金额",
type: "switch",
},
{
prop: "f7",
label: "论文预算费(元)",
placeholder: "请输入金额",
type: "checkbox",
format: "array",
options: [
{
value: "选项1",
label: "黄金糕",
},
{
value: "选项2",
label: "双皮奶",
},
{
value: "选项3",
label: "蚵仔煎",
},
],
},
{
prop: "f8",
label: "论文预算费(元)",
placeholder: "请输入金额",
type: "textarea",
},
{
prop: "f9",
label: "论文预算费(元)",
placeholder: "请输入金额",
type: "number",
},
{
prop: "f10",
label: "论文预算费(元)",
},
{
prop: "sum",
label: "预算总额(元)",
placeholder: "自动计算",
render: (h, params) => {
return [<span>4454545</span>];
},
},
],
};
},
};
</script>
<style scoped>
</style>