1.问题说明
1.准备在filter表头过滤时做后台查询过滤,但无法获取是哪一列
2.avue-crud的filter-change事件中未封装column信息,这样在filter-change方法回调的时候,参数里只有默认的column信息,如果过滤的表头过多,无法判断是哪个列的过滤改变
3.查看column.vue源码发现没有对el-table-colum加入column-key属性
2.代码示例
1.修改avue-crud源码中的column.vue,在el-table-column中加入属性:column-key=“column.columnKey”
<!--此为avue-crud中的源码,实际源码按官网为准,这里只做示范-->
<template>
<div>
<slot name="header"></slot>
<!-- 动态列 -->
<template v-for="(column,index) in list">
<column-dynamic v-if="column.children && column.children.length"
:columnOption="column"
:key="column.label">
<template v-for="item in crud.mainSlot"
slot-scope="scope"
:slot="item.prop">
<slot v-bind="scope"
:name="item.prop"></slot>
</template>
<template v-for="item in crud.headerSlot"
slot-scope="scope"
:slot="crud.getSlotName(item,'H')">
<slot v-bind="scope"
:name="crud.getSlotName(item,'H')"></slot>
</template>
<template v-for="item in crud.mainSlot"
slot-scope="scope"
:slot="crud.getSlotName(item,'F')">
<slot v-bind="scope"
:name="crud.getSlotName(item,'F')"></slot>
</template>
</column-dynamic>
<template v-else-if="!['dynamic'].includes(column.type)">
<el-table-column v-if="vaildColumn(column)"
:key="column.prop"
:prop="column.prop"
:label="column.label"
filter-placement="bottom-end"
:filters="handleFilters(column)"
:filter-method="column.filter? handleFiltersMethod : undefined"
:filter-multiple="vaildData(column.filterMultiple,true)"
:show-overflow-tooltip="column.overHidden"
:min-width="column.minWidth"
:sortable="column.sortable"
:render-header="column.renderHeader"
:align="column.align || tableOption.align"
:header-align="column.headerAlign || tableOption.headerAlign"
:column-key="column.columnKey"
:width="column.width"
:fixed="crud.isMobile?false:column.fixed">
<template slot="header"
slot-scope="scope">
<slot :name="crud.getSlotName(column,'H')"
v-if="crud.$scopedSlots[crud.getSlotName(column,'H')]"
v-bind="Object.assign(scope,{column})"></slot>
<template v-else>{{column.label}}</template>
</template>
<template slot-scope="{row,$index}">
<el-form-item :prop="crud.isTree?'':`list.${$index}.${column.prop}`"
:label="vaildLabel(column,row,' ')"
v-if="row.$cellEdit && column.cell"
:label-width="vaildLabel(column,row,'1px')"
:rules='column.rules'>
<slot v-bind="{
row:row,
dic:crud.DIC[column.prop],
size:crud.isMediumSize,
index:$index,
disabled:crud.btnDisabledList[$index],
label:handleShowLabel(row,column,crud.DIC[column.prop]),
'$cell':row.$cellEdit
}"
:name="crud.getSlotName(column,'F')"
v-if="crud.$scopedSlots[crud.getSlotName(column,'F')]"></slot>
<form-temp v-else
:column="column"
:size="crud.isMediumSize"
:dic="(crud.cascaderDIC[$index] || {})[column.prop] || crud.DIC[column.prop]"
:props="column.props || tableOption.props"
:readonly="column.readonly"
:disabled="crud.disabled || tableOption.disabled || column.disabled || crud.btnDisabledList[$index]"
:clearable="vaildData(column.clearable,false)"
v-bind="$uploadFun(column,crud)"
v-model="row[column.prop]"
@change="columnChange(index,row,column)">
</form-temp>
</el-form-item>
<slot :row="row"
:index="$index"
:dic="crud.DIC[column.prop]"
:size="crud.isMediumSize"
:label="handleShowLabel(row,column,crud.DIC[column.prop])"
:name="column.prop"
v-else-if="crud.$scopedSlots[column.prop]"></slot>
<template v-else>
<span v-if="['img','upload'].includes(column.type)">
<div class="xiaoi-crud__img">
<img v-for="(item,index) in getImgList(row,column)"
:src="item"
:key="index"
@click="openImg(getImgList(row,column),index)" />
</div>
</span>
<span v-else-if="['url'].includes(column.type)">
<el-link v-for="(item,index) in corArray(row[column.prop],column.separator)"
type="primary"
:key="index"
:href="item"
:target="column.target || '_blank'">{{item}}</el-link>
</span>
<span v-else-if="['rate'].includes(column.type)">
<xiaoi-rate disabled
v-model="row[column.prop]" />
</span>
<span v-else
v-html="handleDetail(row,column)"></span>
</template>
</template>
</el-table-column>
</template>
</template>
<slot name="footer"></slot>
</div>
</template>
<script>
import create from "core/create";
import { detail } from "core/detail";
import { sendDic } from "core/dic";
import { DIC_PROPS, DIC_SPLIT } from 'global/variable'
import columnDynamic from "./column-dynamic";
import formTemp from '../../core/components/form/index'
export default create({
name: "crud",
data () {
return {
count: {}
}
},
components: {
formTemp,
columnDynamic
},
inject: ["crud"],
provide () {
return {
crud: this.crud,
dynamic: this
};
},
props: {
tableOption: {
type: Object,
default: () => {
return {};
}
},
columnOption: {
type: Array,
default: () => {
return [];
}
}
},
computed: {
list () {
let result = [...this.columnOption];
return result;
}
},
methods: {
vaildLabel (column, row, val) {
if (column.rules && row.$cellEdit) {
return val
}
},
vaildColumn (item) {
return ((this.crud.$refs.dialogColumn || {}).columnIndex || []).includes(item.prop)
},
corArray (list, separator = DIC_SPLIT) {
if (this.validatenull(list)) {
return []
} else if (!Array.isArray(list)) {
return list.split(separator);
}
return list
},
getImgList (row, column) {
let url = (column.propsHttp || {}).home || ''
let value = (column.props || {}).value || DIC_PROPS.value;
if (this.validatenull(row[column.prop])) return []
if (column.listType == 'picture-img') return [url + row[column.prop]]
let list = this.corArray(this.deepClone(row[column.prop]), column.separator);
list.forEach((ele, index) => {
if (typeof ele === 'object') {
list[index] = url + ele[value];
} else {
list[index] = url + ele;
}
})
return list;
},
handleDetail (row, column) {
let result = row[column.prop];
let DIC = column.parentProp ? (this.crud.cascaderDIC[row.$index] || {})[column.prop] : this.crud.DIC[column.prop]
result = detail(row, column, this.tableOption, DIC);
if (!this.validatenull(DIC)) {
row["$" + column.prop] = result;
}
return result;
},
handleShowLabel (row, column, DIC) {
let result = "";
if (!this.validatenull(DIC)) {
result = detail(row, column, this.tableOption, DIC);
row["$" + column.prop] = result;
}
return result;
},
columnChange (index, row, column) {
if (this.validatenull(this.count[column.prop])) this.count[column.prop] = 0
this.count[column.prop] = this.count[column.prop] + 1;
if (column.cascader) this.handleChange(index, row)
if (this.count[column.prop] % 3 === 0 && typeof column.change === 'function' && column.cell === true) {
column.change({ row, column, index: row.$index, value: row[column.prop] })
}
},
handleChange (index, row) {
this.$nextTick(() => {
const columnOption = [...this.crud.propOption];
//本节点;
const column = columnOption[index];
const list = column.cascader;
const value = row[column.prop];
const rowIndex = row.$index;
// 下一个节点
const columnNext = columnOption[index + 1];
const columnNextProp = columnNext.prop;
// 如果本节点没有字典则创建节点数组
if (this.validatenull(this.crud.cascaderDIC[rowIndex])) {
this.$set(this.crud.cascaderDIC, rowIndex, {});
}
if (this.crud.formIndexList.includes(rowIndex)) {
//清空子类字典
list.forEach(ele => {
this.$set(this.crud.cascaderDIC[rowIndex], ele.prop, []);
list.forEach(ele => (row[ele] = ""));
});
}
//最后一级
if (
this.validatenull(list) ||
this.validatenull(value) ||
this.validatenull(columnNext)
) {
return;
}
sendDic({
column: columnNext,
value: value,
form: row
}).then(
res => {
//首次加载的放入队列记录
if (!this.crud.formIndexList.includes(rowIndex)) this.crud.formIndexList.push(rowIndex);
const dic = Array.isArray(res) ? res : [];
// 修改字典
this.$set(this.crud.cascaderDIC[rowIndex], columnNextProp, dic);
if (!this.validatenull(dic[columnNext.cascaderIndex]) && !this.validatenull(dic) && !this.validatenull(columnNext.cascaderIndex)) {
row[columnNextProp] = dic[columnNext.cascaderIndex][(columnNext.props || {}).value || DIC_PROPS.value]
}
}
);
})
},
openImg (list, index) {
list = list.map(ele => {
return { thumbUrl: ele, url: ele }
})
this.$ImagePreview(list, index);
},
//表格筛选逻辑
handleFiltersMethod (value, row, column) {
const columnNew = this.columnOption.filter(
ele => ele.prop === column.property
)[0];
if (typeof columnNew.filtersMethod === "function") {
return columnNew.filtersMethod(value, row, columnNew);
} else {
return row[columnNew.prop] === value;
}
},
//表格筛选字典
handleFilters (column) {
if (column.filter !== true) return undefined;
if (this.validatenull(column.dicFilters)) {
let list = [];
(this.crud.DIC[column.prop] || []).forEach(ele => {
const props = column.props || this.tableOption.props || {};
list.push({
text: ele[props.label || DIC_PROPS.label],
value: ele[props.value || DIC_PROPS.value]
});
});
return list;
}
return column.dicFilters;
}
}
});
</script>
2.tableOption中的配置,添加配置columnKey: ‘status’
export const tableOption = {
menu: true,
index: false,
indexLabel: '序号',
stripe: true,
menuWidth: '100px',
menuAlign: 'center',
align: 'center',
editBtn: false,
delBtn: true,
delBtnDisabled: false,
addBtn: false,
dic: [],
searchMenuShow: false,
selection: true,
emptyText: '暂无数据',
dialogType: 'drawer',
labelPosition: 'top',
column: [
{
label: '状态',
prop: 'status',
width: 110,
slot: true,
filter: true,
filterMultiple: false,
columnKey: 'status',
dicData: [{ label: '待训练', value: 20 }, { label: '已生效', value: 15 }, { label: '已禁用', value: 1 }, { label: '同步失败', value: 10 }, { label: '同步中', value: 5 }],
filterMethod: function(value, row) {
return row.status === value
}
}
]
}
3.avue-curd代码中,添加filter-change事件
<avue-crud
ref="crud"
:option="tableOption"
:page.sync="page"
:data="tableData"
:table-loading="tableLoading"
@on-load="getList"
@filter-change="filterChange"
>
</avue-crud>
4.filterChange方法代码
methods: {
filterChange(filters){
//如果不配置columnKey,filters的key默认为column数字,无法判断是哪一列,配置了columnKey便能判断是哪一列的过滤条件,根据这个过滤条件便可以进行后端过滤操作
if(filters && filters.status != undefined) {
var array = filters.status;
var status = '';
array.forEach(element => {
status += element + ','
});
if(status.indexOf(",")){
status = status.substring(0,status.length-1)
}
this.searchForm.searchStatus = status;
this.getList(this.page)
}
}
}