305 lines
11 KiB
Vue
305 lines
11 KiB
Vue
<template>
|
||
<a-table
|
||
v-bind="$attrs"
|
||
v-on="$listeners"
|
||
:bordered="bordered"
|
||
:scroll="{x: '100%'}"
|
||
:columns="columns"
|
||
:data-source="dataSource">
|
||
<!-- 如果插槽是作用域插槽,将作用域插槽的props包装成对象传递给slot -->
|
||
<template v-for="(_, slotName) in $scopedSlots" :slot="slotName" slot-scope="text, record, index">
|
||
<slot :name="slotName" v-bind="{text, record, index}" />
|
||
</template>
|
||
<!-- 如果是普通插槽,直接使用$slots渲染 -->
|
||
<slot v-for="(_, slotName) in $slots" :name="slotName" :slot="slotName" />
|
||
<!-- 文本悬浮插槽 -->
|
||
<template slot="text" slot-scope="text">
|
||
<a-tooltip overlay-class-name="tooltip-style">
|
||
<template slot="title">{{ text || text === 0 ? text : global.emptyLine }}</template>
|
||
<div class="table-text">{{ text || text === 0 ? text : global.emptyLine }}</div>
|
||
</a-tooltip>
|
||
</template>
|
||
<!-- 表格扩展插槽 -->
|
||
<div slot="expandedRowRender" slot-scope="record, index" style="margin: 0">
|
||
<!-- 如果表单会依赖某个字段变化就需要加判断,循环判断extraForm中的表单 -->
|
||
<template v-if="formIsDepend">
|
||
<template v-for="(value, key) in extraForm">
|
||
<template v-if="record[formIsDepend] === key">
|
||
<a-form-model :key="key" :model="record" :rules="value.rules" :ref="`ruleForm${index}`">
|
||
<a-form-model-item v-for="form in value.formArr" :key="form.dbFieldName" :labelCol="labelCol" :wrapperCol="wrapperCol" :label="form.dbFieldTxt" :prop="form.dbFieldName">
|
||
<template v-if="form.fieldShowType === 1">
|
||
<a-input
|
||
type="textarea"
|
||
:maxLength="500"
|
||
:placeholder="$t('pleaseEnter')+form.dbFieldTxt"
|
||
:disabled="allDisabled || form.isDisabled || false"
|
||
v-model="record[form.dbFieldName]" />
|
||
</template>
|
||
<template v-else-if="form.fieldShowType === 2">
|
||
<j-upload
|
||
return-id
|
||
v-model="record[form.dbFieldName]"
|
||
:disabled="allDisabled || form.isDisabled || false"
|
||
:file-type="form.fileType || canUploadType">
|
||
</j-upload>
|
||
</template>
|
||
<template v-else-if="form.fieldShowType === 3">
|
||
<a-date-picker
|
||
value-format="YYYY-MM-DD"
|
||
format="YYYY-MM-DD"
|
||
:disabled="allDisabled || form.isDisabled || false"
|
||
v-model="record[form.dbFieldName]">
|
||
</a-date-picker>
|
||
</template>
|
||
<template v-else-if="form.fieldShowType === 4">
|
||
<a-input
|
||
:maxLength="50"
|
||
:placeholder="$t('pleaseEnter')+form.dbFieldTxt"
|
||
:disabled="allDisabled || form.isDisabled || false"
|
||
v-model="record[form.dbFieldName]" />
|
||
</template>
|
||
</a-form-model-item>
|
||
</a-form-model>
|
||
</template>
|
||
</template>
|
||
</template>
|
||
<!-- 没有依赖的字段,就直接把传入的extraForm数组渲染成表单 -->
|
||
<template v-else>
|
||
<a-form-model :model="record" :rules="extraForm.rules" :ref="`ruleForm${index}`">
|
||
<a-form-model-item v-for="form in extraForm.formArr" :key="form.dbFieldName" :labelCol="labelCol" :wrapperCol="wrapperCol" :label="form.dbFieldTxt" :prop="form.dbFieldName">
|
||
<template v-if="form.fieldShowType === 1">
|
||
<a-input
|
||
type="textarea"
|
||
:maxLength="500"
|
||
:disabled="allDisabled || form.isDisabled || false"
|
||
:placeholder="$t('pleaseEnter')+form.dbFieldTxt"
|
||
v-model="record[form.dbFieldName]" />
|
||
</template>
|
||
<template v-else-if="form.fieldShowType === 2">
|
||
<j-upload
|
||
return-id
|
||
v-model="record[form.dbFieldName]"
|
||
:disabled="allDisabled || form.isDisabled || false"
|
||
:file-type="form.fileType || canUploadType">
|
||
</j-upload>
|
||
</template>
|
||
<template v-else-if="form.fieldShowType === 3">
|
||
<a-date-picker
|
||
value-format="YYYY-MM-DD"
|
||
format="YYYY-MM-DD"
|
||
:disabled="allDisabled || form.isDisabled || false"
|
||
v-model="record[form.dbFieldName]">
|
||
</a-date-picker>
|
||
</template>
|
||
<template v-else-if="form.fieldShowType === 4">
|
||
<a-input
|
||
:maxLength="50"
|
||
:placeholder="$t('pleaseEnter')+form.dbFieldTxt"
|
||
:disabled="allDisabled || form.isDisabled || false"
|
||
v-model="record[form.dbFieldName]" />
|
||
</template>
|
||
</a-form-model-item>
|
||
</a-form-model>
|
||
</template>
|
||
</div>
|
||
</a-table>
|
||
</template>
|
||
|
||
<!--
|
||
使用方法:
|
||
html:
|
||
<j-expand-table :formIsDepend="formIsDepend" :extraForm="extraForm"></j-expand-table>
|
||
1、如果扩展中的表单会根据某个字段变化,就传formIsDepend=随之变化的字段名,extraForm就传
|
||
extraForm: {
|
||
1: { // 1表示formIsDepend对应的字段值是1
|
||
rules: { // formIsDepend对应的字段值是1时的表单验证
|
||
desc: { required: true, message: '请输入依据描述', trigger: 'blur' },
|
||
...
|
||
},
|
||
formArr: [// formIsDepend对应的字段值是1时的表单数据
|
||
{
|
||
fieldShowType: 1,
|
||
dbFieldTxt: this.$t(''), // 标签文本
|
||
dbFieldName: 'desc', // dataSource中对应的字段名
|
||
isDisabled: true // false的话可以不传
|
||
},
|
||
...
|
||
]
|
||
},
|
||
},
|
||
2、如果扩展中的表单是固定的,extraForm就传
|
||
extraForm: {
|
||
rules: {
|
||
desc: { required: false, message: '请输入依据描述', trigger: 'blur' },
|
||
...
|
||
},
|
||
formArr: [
|
||
{
|
||
fieldShowType: 1,
|
||
dbFieldTxt: this.$t(''), // 标签文本
|
||
dbFieldName: 'desc', // dataSource中对应的字段名
|
||
isDisabled: true // false的话可以不传
|
||
},
|
||
...
|
||
]
|
||
}
|
||
3、提交时调用该组件中的submit方法获取返回值:
|
||
返回值为false说明没有通过表单校验,为true说明通过了校验,直接通过绑定的dataSource获取数据即可,示例如下:
|
||
// 获取表格扩展部分的校验结果
|
||
const result = this.$refs.jExpandTable.submit()
|
||
if (result) {
|
||
// 每个表单校验都通过了
|
||
console.log('通过了', this.dataSource)
|
||
} else {
|
||
// 有表单没有通过
|
||
this.$message.warning('请输入必填项')
|
||
}
|
||
|
||
-->
|
||
<script>
|
||
import JUpload from './jero/JUpload'
|
||
|
||
export default {
|
||
name: 'JExpandTable',
|
||
components: { JUpload },
|
||
props: {
|
||
columns: {
|
||
type: Array,
|
||
default: () => {
|
||
return []
|
||
}
|
||
},
|
||
dataSource: {
|
||
type: Array,
|
||
default: () => {
|
||
return []
|
||
}
|
||
},
|
||
bordered: {
|
||
type: Boolean,
|
||
default: false
|
||
},
|
||
/**
|
||
* 扩展区表单, 表单需要依赖某个字段判断的就用对象,key是字段对应值,value是字段值对应下的表单数组
|
||
* 表单数组格式如下:
|
||
* [
|
||
* {
|
||
* fieldShowType: // 字段类型: 1,多行文本;2, 上传文件; 3, 日期选择; 4, 单行文本,
|
||
* dbFieldTxt: // 标签文本,例如:依据描述,
|
||
* dbFieldName: // 字段名
|
||
* isDisabled: // 是否可编辑
|
||
* }
|
||
* ]
|
||
*/
|
||
extraForm: {
|
||
type: Object,
|
||
default: () => {
|
||
return {}
|
||
}
|
||
},
|
||
/**
|
||
* 表单是否有依赖,传false或者依赖字段名
|
||
*/
|
||
formIsDepend: {
|
||
type: [Boolean, String],
|
||
default: false
|
||
},
|
||
// 全部禁用
|
||
allDisabled: {
|
||
type: Boolean,
|
||
required: false,
|
||
default: false
|
||
}
|
||
},
|
||
data () {
|
||
return {
|
||
labelCol: {
|
||
sm: 4
|
||
},
|
||
wrapperCol: {
|
||
sm: 16
|
||
},
|
||
// 本系统限制可以上传的文件格式
|
||
canUploadType: 'pdf,docx,doc,xlsx,xls,ppt,pptx,rar,zip,jpg,jpeg,png,avi,wmv,mov,rm,mp4,cad'
|
||
}
|
||
},
|
||
methods: {
|
||
submit () {
|
||
const arr = []
|
||
for (const i in this.dataSource) {
|
||
if (this.$refs[`ruleForm${i}`] && this.$refs[`ruleForm${i}`][0]) {
|
||
this.$refs[`ruleForm${i}`][0].validate(valid => {
|
||
arr[i] = valid
|
||
})
|
||
} else {
|
||
// arr[i] = false
|
||
// 表单都没有渲染,说明没有展开过,也就是未填状态
|
||
if (this.formIsDepend) {
|
||
if (this.dataSource[i][this.formIsDepend]) {
|
||
// 需要依赖某个字段,获取当前行该字段时,扩展表单是否有必填项
|
||
// console.log(this.dataSource[i])
|
||
// console.log(this.extraForm[this.dataSource[i][this.formIsDepend]])
|
||
const currRowExtraFormFormArr = this.extraForm[this.dataSource[i][this.formIsDepend]].formArr
|
||
const currRowExtraFormRules = this.extraForm[this.dataSource[i][this.formIsDepend]].rules
|
||
let isHaveRequired = false
|
||
for (const item of currRowExtraFormFormArr) {
|
||
if (currRowExtraFormRules[item.dbFieldName].required === true && !this.dataSource[i][item.dbFieldName]) {
|
||
// 有必填但没有填内容
|
||
isHaveRequired = true
|
||
}
|
||
}
|
||
// for (const item in currRowExtraFormRules) {
|
||
// if (currRowExtraFormRules[item].required === true) {
|
||
// // 有任意一个字段有必填,但没有内容
|
||
// isHaveRequired = true
|
||
// }
|
||
// }
|
||
if (isHaveRequired) {
|
||
// 任意一个字段有必填,她又没展开过,校验不通过
|
||
arr[i] = false
|
||
} else {
|
||
arr[i] = true
|
||
}
|
||
} else {
|
||
// 依赖的字段都没有填
|
||
arr[i] = false
|
||
}
|
||
} else {
|
||
// 没有依赖的字段
|
||
let isHaveRequired = false
|
||
for (const item of this.extraForm.formArr) {
|
||
if (this.extraForm.rules[item.dbFieldName].required === true && !this.dataSource[i][item.dbFieldName]) {
|
||
// 有字段有必填,但没有内容
|
||
isHaveRequired = true
|
||
}
|
||
}
|
||
// for (const item in this.extraForm.rules) {
|
||
// if (this.extraForm.rules[item].required === true) {
|
||
// // 有任意一个字段有必填
|
||
// isHaveRequired = true
|
||
// }
|
||
// }
|
||
if (isHaveRequired) {
|
||
// 任意一个字段有必填,她又没展开过,校验不通过
|
||
arr[i] = false
|
||
} else {
|
||
arr[i] = true
|
||
}
|
||
}
|
||
}
|
||
}
|
||
console.log(arr)
|
||
if (arr.includes(false)) {
|
||
return false
|
||
} else {
|
||
return true
|
||
}
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style scoped>
|
||
|
||
</style>
|