vxe-table封装表头
待补充使用说明,但是可以用
- 一.效果
- 二.封装MyTable.vue
- 1.封装index.vue
- 2.日期选择筛选
- 3.输入筛选
- 4.下拉筛选
- 5.多选筛选
- 6.远程多选筛选
- 7.远程单选筛选
- 三、页面使用
- 1.具体页面使用
- 2.@/utils/filter.js
注意:需要使用jsx、vxe-table、element-plus
一.效果
二.封装MyTable.vue
注意:6和7涉及远程获取下拉数据的接口,你们可能不适应,但可借鉴实现方式
注意:6和7涉及远程获取下拉数据的接口,你们可能不适应,但可借鉴实现方式
注意:6和7涉及远程获取下拉数据的接口,你们可能不适应,但可借鉴实现方式
筛选图的图片自己随意搞两个即可
注意:import { queryDropDownList } from "@/api/service.js" // 使用页当前列key下拉如果是传递空数组selectList: [],需要使用该方法从后端获取下拉数据
1.封装index.vue
src/components/MyTable/index.vue
<template><div class="page-view flex-column" @click="handleClickOutside"><div style="width: 100%" class="flex-between" :class="[props.noPb ? '' : 'pb']"><div style="display: flex; color: #333; font-weight: 700"><slot name="titleContent"></slot></div><div style="display: flex"><el-button type="primary" plain @click="resetFilters">重置</el-button><slot name="btnContent"></slot><vxe-toolbar @click="clickToolbar" style="padding: 0 !important; height: 30px; margin-left: 10px" v-if="!tableData.hideCustom" ref="toolbarRef" custom></vxe-toolbar></div></div><slot name="pageAccount"></slot><div style="flex: 1; overflow-y: auto; scrollbar-gutter: stable"><!-- :key="keyIndex" --><vxe-gridref="xTable"v-bind="tableData":data="props.dataList"@checkbox-all="selectAllEvent"@checkbox-change="selectChangeEvent"@radio-change="radioChangeEvent"@sort-change="sortChangeEvent"><template v-for="(item, index) in tableData.columns" :key="index" v-slot:[`${item.field}`]="{ }"><div><div class="table-header-div"><span class="title-span"><my-tooltips :content="item.title ?? ''" /></span><!-- 控制筛选按钮显隐 --><template v-if="item.field !== 'actionBtn' && item.formType"><el-popover :visible="visible && item.field === showKey" :virtual-ref="refName" placement="bottom" :width="'fit-content'"><template #reference><!-- 两个筛选icon --><imgv-if="((searchData[item.field] || searchData[item.field] === 0) && !Array.isArray(searchData[item.field])) ||(Array.isArray(searchData[item.field]) && searchData[item.field].length > 0)":id="item.field"@click.stop="toggleNameFilter(item.field, item)"class="icon icon-span"src="./components/filterActive.png"/><img v-else :id="item.field" @click.stop="toggleNameFilter(item.field, item)" class="icon icon-span" src="./components/filterDefault.png" /></template><div @click.stop="() => {}"><div style="text-align: right"><el-button type="info" link @click="cancelFilter">重置</el-button><el-button type="primary" link @click="searchFilter">筛选</el-button></div><!-- 各类筛选组件 --><component:is="componentName[item.formType]"v-model="searchData[item.field]":list="item.selectList":type="item.formType":format="item.dateType":itemRow="item":requestApi="item.requestApi"@handleEnter="searchFilter"></component></div></el-popover></template></div></div></template><template #empty><jg-empty :type="emptyType" v-if="!loading" /></template></vxe-grid></div><!-- <pre>筛选和排序参数:{{ { ...searchData, ...sortJavaField } }}</pre></pre> --><!-- <pre>表格默认多列排序集合:{{ sortField }}</pre> --><!-- <pre>表格参数:{{ tableData }}</pre> --></div>
</template><script setup lang="jsx">
import { ref, watch, shallowRef, nextTick, onMounted, onBeforeUnmount } from "vue" // 按需引入ref函数
import { queryDropDownList } from "@/api/service.js" // 当前列下拉如果是传递空数组,需要使用该方法从后端获取下拉数据
import _ from "lodash"import InputFilter from "./components/input.vue"
import SelectFilter from "./components/select.vue"
import SelectRemoteFilter from "./components/selectRemote.vue"
import SelectMultipleFilter from "./components/selectMultiple.vue"
import SelectMultipleRemoteFilter from "./components/selectMultipleRemote.vue"
import DatePickerFilter from "./components/datePicker.vue"const componentName = ref({input: shallowRef(InputFilter),select: shallowRef(SelectFilter),selectRemote: shallowRef(SelectRemoteFilter),selectMultiple: shallowRef(SelectMultipleFilter),selectMultipleRemote: shallowRef(SelectMultipleRemoteFilter),daterange: shallowRef(DatePickerFilter),datetimerange: shallowRef(DatePickerFilter)
})defineOptions({name: "JgTable"
})const emit = defineEmits(["searchEvent", "checkboxEvent", "radioEvent", "updateSortChange"])const props = defineProps({tableDataObj: {type: Object,default: () => {return {}}},dataList: {type: Array,default: () => {return []}},emptyType: {type: String,default: "noResult"},// 是否展示展位图loading: {type: Boolean,default: false},noPb: {type: Boolean,default: false},
})let tableFlag = ref(false) //确保拿到父传子的表格数据再渲染
let keyIndex = ref(0) // 表格key
let tableData = ref({})
const toolbarRef = ref(null) // 工具栏
let xTable = ref(null) // 表格实例let searchData = ref({}) // 搜索参数 每个表头字段
// let sortObj = ref({}) // 单列排序
const sortField = ref({}) // 表格默认多列排序集合
const sortJavaField = ref({sortList: []
}) // 后端要的排序集合const showKey = ref(undefined) // 当前展示哪个筛选窗
const visible = ref(false) // 手动控制筛选窗显隐
const refName = ref(null) // 动态绑定在哪个表头图标下// 全局重置
const resetFilters = () => {for (const key in searchData.value) {if (Object.hasOwnProperty.call(searchData.value, key)) {searchData.value[key] = undefined}}visible.value = falseif (xTable.value) {xTable.value.clearCheckboxRow()}if (xTable.value) {xTable.value.clearRadioRow()}if (xTable.value) {xTable.value.clearSort()}sortField.value = {}sortJavaField.value.sortList = []// 因为无法通过element ui的api来清除排序样式,所以只能通过原生js来清除xTable.value.$el.querySelectorAll(".is-sortable").forEach(item => {// 移除table表头中的排序样式descending和ascendingitem.classList.remove("descending")item.classList.remove("ascending")}) // 清除多个排序// xTable.value.clearSort() // 清除单个排序getData()
}// 触发筛选
const toggleNameFilter = async (key, item) => {// console.log(key, item);if (_.isEmpty(item.selectList) && (item.formType === "selectMultiple" || item.formType === "select")) {await getJavaList(item) // 调用后端接口 获取下拉数据}// if (item.formType === 'selectMultipleRemote') {// await getJavaList() // 调用后端接口 获取下拉数据// }if (visible.value && showKey.value && showKey.value !== key) {visible.value = falsegetData()}refName.value = document.getElementById(key)showKey.value = keyvisible.value = !visible.value
}// 某些下拉数据 例如下拉大数据有500条 直接赋值会导致表格卡顿 通过点击表头再去接口获取数据赋值就不会影响表格的渲染
// (列里面数据回显使用后端给的中文,或者将javaList赋值给item的selectList)
let javaList = ref([])
const getJavaList = async item => {await queryDropDownList({fieldCode: item.field,...item.requestData}).then((res = []) => {// res = Array.from({ length: 200 }).map((ele, index) => {// return {// name: '下拉' + item.field + index,// value: index,// }// })javaList.value = res || []item.selectList = javaList.value || []}).finally(() => {})
}// 点击其他元素
const handleClickOutside = () => {// 且有筛选打开即去查询// if (visible.value) {// visible.value = false// // getData()// }
}// 重置
const cancelFilter = () => {searchData.value[showKey.value] = undefinedvisible.value = falsegetData()
}
// 筛选
const searchFilter = () => {visible.value = falsegetData()
}// 实时获取表头
const getRealData = () => {return { ...searchData.value, ...sortJavaField.value }
}
// 关闭表头弹框
// 点击其他元素
const handleCloseOutside = () => {// 且有筛选打开即去查询if (visible.value) {visible.value = false// getData()}
}
const getData = () => {console.log("筛选参数", { ...searchData.value, ...sortJavaField.value })emit("searchEvent", { ...searchData.value, ...sortJavaField.value })
}watch(() => props.dataList,() => {nextTick(() => {keyIndex.value++ // 原用来强制刷新列表渲染解决指令问题,后指令问题解决了。但强制刷新会触发表格重绘,导致排序效果消失和工具栏二次触发才有效,故不在使用强制刷新})},{ deep: true, immediate: false }
)
watch([() => props.tableDataObj],([tableDataObj]) => {// console.log('监听');tableFlag.value = false// console.log(tableDataObj)tableData.value = _.cloneDeep(tableDataObj) // 使用lodash的深拷贝方法// 表格全部增加hover效果tableData.value.rowConfig = { isHover: true }tableFlag.value = true// 判断空 也就是初次渲染时候需要排列出查询参数 后续数据变动不在初始化不在设置为undefined 否则会导致每次查询清空掉上次筛选条件// if (_.isEmpty(searchData.value)) {tableDataObj?.columns.forEach(ele => {if (ele.field) {searchData.value[ele.field] = ele.defaultValue || undefined}// 统一设置插槽头名称if (ele?.slots === undefined || ele?.slots === null || ele?.slots == {}) {ele.slots = {header: ele.field}}if (ele?.slots?.header === undefined || ele?.slots?.header === null) {ele.slots.header = ele.field}})// }},{ deep: true, immediate: true }
)// 多选
const selectAllEvent = () => {let val = xTable.value.getCheckboxRecords()emit("checkboxEvent", val)
}
const selectChangeEvent = () => {let val = xTable.value.getCheckboxRecords()emit("checkboxEvent", val)
}
// 清除所有行选中
const clearSelectEvent = () => {if (xTable.value) {xTable.value.clearCheckboxRow()}
}
// 单选事件
const radioChangeEvent = ({ row }) => {emit("radioEvent", row)
}
// 更新表格数据’
const updateTableDatas = data => {if (xTable.value) {xTable.value.loadData(data)}
}// 动态显隐列
const refreshColumns = () => {// console.log(field, isShow);if (xTable.value) {xTable.value.refreshColumn()}
}// 多列排序
const sortChangeEvent = ({ sortList }) => {// console.log(column, field, order, sortBy, sortList, $event)// console.log(sortList)sortJavaField.value.sortList = []sortJavaField.value.sortList = sortList.map(ele => {return {sortName: ele.field,sortType: ele.order === "desc" ? "DESC" : ele.order === "asc" ? "ASC" : undefined}})getData() // 直接统一在筛选里加入排序字段
}nextTick(() => {// 将表格和工具栏进行关联const $table = xTable.valueconst $toolbar = toolbarRef.valueif ($table && $toolbar) {$table.connect($toolbar)}
})
// 手动解决 因设置 :key 导致有概率不触发工具栏问题
const clickToolbar = () => {setTimeout(() => {// 将表格和工具栏进行关联const $table = xTable.valueconst $toolbar = toolbarRef.valueif ($table && $toolbar) {$table.connect($toolbar)}}, 100)
}const handleClickOther = () => {// 且有筛选打开即去查询if (visible.value) {visible.value = falsegetData()}
};// 在组件挂载时添加全局点击事件监听器
onMounted(() => {window.addEventListener('click', handleClickOther);
});// 在组件卸载时移除全局点击事件监听器
onBeforeUnmount(() => {window.removeEventListener('click', handleClickOther);
});defineExpose({clearSelectEvent,resetFilters,updateTableDatas,refreshColumns,getRealData,handleCloseOutside
})
</script><style lang="scss" scoped>
.page-view {height: 100%;width: 100%;
}.flex-start {display: flex;justify-content: flex-start;align-items: center;
}.flex-end {display: flex;justify-content: flex-end;
}.flex-column {display: flex;flex-direction: column;
}.flex-row {display: flex;flex-direction: row;
}.flex-between {display: flex;justify-content: space-between;align-items: center;
}.mr {margin-right: 16px;
}.ml {margin-left: 16px;
}.mt {margin-top: 12px;
}.mb {margin-bottom: 12px;
}.m0 {margin: 0;
}:deep(.vxe-grid) {thead {.vxe-cell {min-width: 64px;// padding-left: 0px !important;// 针对vxe-table4.7 结构修改↓display: flex;.vxe-cell--title {overflow: hidden;}.vxe-cell--sort-vertical-layout {width: 20px;}// 针对vxe-table4.7 结构修改↑}.table-header-div {display: flex;.title-span {min-width: 20px;white-space: nowrap;text-overflow: ellipsis;overflow: hidden;word-break: break-all;// background-color: #1fff;// white-space: pre-wrap;}.icon-span {width: 20px;height: 20px;flex-shrink: 0;margin-top: 1px;margin-left: 5px;cursor: pointer;/* 防止缩小 *//* 给图标和标题之间添加一些间距 */}}}
}
</style>
2.日期选择筛选
src/components/MyTable/components/datePicker.vue
<template><el-date-pickerstyle="width: 360px"v-model="localValue":type="props.type"range-separator="~"start-placeholder="开始时间"end-placeholder="结束时间":format="props.format":default-time="defaultTime"@change="changeData($event, 'item.field', props.format)"/>
</template>
<script setup lang="jsx">
import { ref, watch } from "vue" // 按需引入ref函数
import _ from "lodash"
import dayjs from "dayjs"const emit = defineEmits(["update:modelValue"])defineOptions({name: "DatePicker"
})const props = defineProps({modelValue: {// 父组件 v-model 时数据没有指定参数名,所以此时属性modelValue会接收到v-model变量type: Array,default: () => {return []}},type: {type: String,default: () => {return "daterange"}},format: {type: String,default: () => {return "YYYY-MM-DD"}}
})const localValue = ref(props.modelValue || [])
const defaultTime = [new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 2, 1, 23, 59, 59)] // '12:00:00', '08:00:00'watch(() => props.modelValue,newValue => {localValue.value = newValue}
)// 时间格式化
const changeData = (value, key, dateType) => {// console.log(value, key, dateType);if (!_.isEmpty(value)) {localValue.value[0] = value[0] ? dayjs(value[0]).format(dateType) : ""localValue.value[1] = value[1] ? dayjs(value[1]).format(dateType) : ""} else {localValue.value = []}emit("update:modelValue", localValue.value)
}
</script>
3.输入筛选
src/components/MyTable/components/input.vue
<template><el-input v-model="localValue" placeholder="请输入" clearable style="margin-top: 10px; width: 150px" @change="handleChange" @keyup.enter="handleEnter" maxlength="100"/>
</template>
<script setup lang="jsx">
import { ref, watch } from "vue" // 按需引入ref函数const emit = defineEmits(["update:modelValue", "handleEnter"])defineOptions({name: "SelectMultipleFilter"
})const props = defineProps({modelValue: {type: String,default: () => {return undefined}}
})const localValue = ref(props.modelValue || undefined)watch(() => props.modelValue,newValue => {localValue.value = newValue}
)const handleChange = () => {emit("update:modelValue", localValue.value)
}
const handleEnter = () => {emit("handleEnter")
}
</script>
4.下拉筛选
src/components/MyTable/components/select.vue
<template><el-select filterable :reserve-keyword="false" v-model="localValue" placeholder="请选择" clearable style="margin-top: 10px; width: 160px" @change="handleChange" v-limit-length="100"><el-option v-for="item in list" :key="item" :value="item.value" :label="item.name" /></el-select>
</template>
<script setup lang="jsx">
import { ref, watch } from "vue" // 按需引入ref函数const emit = defineEmits(["update:modelValue"])defineOptions({name: "SelectMultipleFilter"
})const props = defineProps({modelValue: {type: [String, Number],default: () => {return undefined}},list: {type: Array,default: () => {return []}}
})const localValue = ref(props.modelValue || undefined)watch(() => props.modelValue,newValue => {localValue.value = newValue}
)const handleChange = () => {emit("update:modelValue", localValue.value)
}
</script>
5.多选筛选
src/components/MyTable/components/selectMultiple.vue
<template><el-select multiple collapse-tags filterable :reserve-keyword="false" v-model="localValue" placeholder="请选择" clearable style="margin-top: 10px; width: 160px" v-limit-length="100" @change="handleChange"><el-option v-for="item in list" :key="item" :value="item.value" :label="item.name" /></el-select>
</template>
<script setup lang="jsx">
import { ref, watch } from "vue" // 按需引入ref函数const emit = defineEmits(["update:modelValue"])defineOptions({name: "SelectMultipleFilter"
})const props = defineProps({modelValue: {type: Array,default: () => {return []}},list: {type: Array,default: () => {return []}}
})const localValue = ref(props.modelValue || [])watch(() => props.modelValue,newValue => {localValue.value = newValue}
)const handleChange = () => {emit("update:modelValue", localValue.value)
}
</script>
6.远程多选筛选
src/components/MyTable/components/selectMultipleRemote.vue
<template><el-selectmultiplecollapse-tagsfilterableremote:reserve-keyword="false":loading="listLoading"remote-show-suffix:remote-method="remoteMethod"v-model="localValue"placeholder="请搜索后选择"clearablestyle="margin-top: 10px; width: 160px"@change="handleChange"v-limit-length="100"><el-option v-for="item in javaList" :key="item" :value="item.value" :label="item.name" /></el-select>
</template>
<script setup lang="jsx">
import { ref, watch } from "vue" // 按需引入ref函数
// import { useList } from '@/service/index.js'
import { queryDropDownPage } from "@/api/service.js"const emit = defineEmits(["update:modelValue"])defineOptions({name: "SelectMultipleFilter"
})const props = defineProps({modelValue: {// 父组件 v-model 时数据没有指定参数名,所以此时属性modelValue会接收到v-model变量type: Array,default: () => {return []}},itemRow: {// 当前列对象type: Object,default: () => {return {}}},requestApi: {// 自定义筛选apitype: Function,default: null}
})const localValue = ref(props.modelValue || [])watch(() => props.modelValue,newValue => {localValue.value = newValue}
)// 某些下拉数据 例如下拉大数据有500条 直接赋值会导致表格卡顿 通过点击表头再去接口获取数据赋值就不会影响表格的渲染
// (列里面数据回显使用后端给的中文,或者将javaList赋值给item的selectList)
let javaList = ref([])
const listLoading = ref(false)
// 远程搜索接口获取下拉数据
const remoteMethod = query => {if (query) {listLoading.value = truelet api = props?.requestApi || queryDropDownPage // 自定义筛选事件和通用筛选事件api({pageNum: 1,pageSize: 100,searchKeyword: query,fieldCode: props.itemRow.field,...props.itemRow.requestData}).then((res = {}) => {// res = Array.from({ length: 100 }).map((ele, index) => {// return {// name: query + props.itemRow.field + index,// value: index,// }// })javaList.value = res?.records || []}).finally(() => {listLoading.value = false})} else {// javaList.value = []}
}const handleChange = () => {emit("update:modelValue", localValue.value)
}
</script>
7.远程单选筛选
src/components/MyTable/components/selectRemote.vue
<template><el-selectfilterableremote:reserve-keyword="false":loading="listLoading"remote-show-suffix:remote-method="remoteMethod"v-model="localValue"placeholder="请搜索后选择"clearablestyle="margin-top: 10px; width: 160px"@change="handleChange"v-limit-length="100"><el-option v-for="item in javaList" :key="item" :value="item.value" :label="item.name" /></el-select>
</template>
<script setup lang="jsx">
import { ref, watch } from "vue" // 按需引入ref函数
// import { useList } from '@/service/index.js'
import { queryDropDownPage } from "@/api/service.js"const emit = defineEmits(["update:modelValue"])defineOptions({name: "SelectMultipleFilter"
})const props = defineProps({modelValue: {// 父组件 v-model 时数据没有指定参数名,所以此时属性modelValue会接收到v-model变量type: [String, Number],default: () => {return undefined}},itemRow: {// 当前列对象type: Object,default: () => {return {}}}
})const localValue = ref(props.modelValue || undefined)watch(() => props.modelValue,newValue => {localValue.value = newValue}
)// 某些下拉数据 例如下拉大数据有500条 直接赋值会导致表格卡顿 通过点击表头再去接口获取数据赋值就不会影响表格的渲染
// (列里面数据回显使用后端给的中文,或者将javaList赋值给item的selectList)
let javaList = ref([])
const listLoading = ref(false)
// 远程搜索接口获取下拉数据
const remoteMethod = query => {if (query) {listLoading.value = truequeryDropDownPage({pageNum: 1,pageSize: 100,searchKeyword: query,fieldCode: props.itemRow.field,...props.itemRow.requestData}).then((res = {}) => {// res = Array.from({ length: 100 }).map((ele, index) => {// return {// name: query + props.itemRow.field + index,// value: index,// }// })javaList.value = res?.records || []}).finally(() => {listLoading.value = false})} else {// javaList.value = []}
}const handleChange = () => {emit("update:modelValue", localValue.value)
}
</script>
三、页面使用
1.具体页面使用
注意:其实只需要关注tableSetting这个配置式表格即可
<template><MyTable :tableDataObj="tableSetting" :dataList="tableData" @searchEvent="searchEvent" @checkboxEvent="checkboxEvent" @radioEvent="radioEvent"><template v-slot:titleContent><b>模板列表</b></template><template v-slot:btnContent><el-button :icon="CirclePlus" type="primary">右侧插槽内容</el-button></template></MyTable><my-pagination v-model:pageNum="queryForm.pageNum" v-model:pageSize="queryForm.pageSize" :totalNum="totalNum" @getList="getList"></my-pagination><!-- 编辑 --><el-dialog class="dialog-box" v-model="dialogItemObj.dialogVisible" :close-on-click-modal="false" :title="dialogItemObj.title" align-center width="720" style="min-height: 280px"><div style="height: 300px">弹框内容</div><!-- <FormInfo v-loading="formEditLoading" :formType="dialogItemObj.formType" :dataForm="dialogItemObj.dataForm" ref="formInfo"></FormInfo> --><template #footer><el-button @click="resetApplication()">取消</el-button><el-button type="primary" @click="submitApp()">提交</el-button></template></el-dialog>
</template><script setup lang="jsx">
defineOptions({name: 'Muban'
})
import { ref, onMounted, } from "vue"
import { CirclePlus } from '@element-plus/icons-vue'
// import { operateRuleConfig, delRuleConfig, } from "@/api/policyConfiguration.js" // 获取接口
let operateRuleConfig // 假设接口1
let delRuleConfig // 假设接口2
import { getDefaultValue, replaceStr, filters } from '@/utils/filter.js' // 表格查询参数处理
import { ElMessage, ElMessageBox } from "element-plus"
// import FormInfo from './components/formInfo.vue'const nameList = ref([]) // 下拉数据
const moreList = ref([{ name: '值1', value: 1 },{ name: '值2', value: 2 },
])
const tableSetting = ref({loading: false,size: 'small',showOverflow: 'tooltip',height: '100%',id: 'tableId_dataReport_01',// 唯一性idcustomConfig: {storage: true,checkMethod: ({ column }) => {return !['radio_key', 'seq_key', 'actionBtn'].includes(column.field)},}, // 自定义配置列radioConfig: {labelField: 'name',checkMethod: ({ row }) => {return row.jj !== 2}}, // 单选配置个别禁选择checkboxConfig: {labelField: 'name',checkMethod: ({ row }) => {return row.jj !== 2}}, // 多选配置个别禁选择sortConfig: { multiple: true, remote: true, chronological: false, }, // 多列排序columns: [{ type: 'radio', field: 'radio_key', width: 50 },{ type: 'checkbox', width: 50 },{ type: 'seq', field: 'seq_key', title: '序号', width: 50 },{ title: '长文本换行', field: 'aa', formType: 'input', sortable: true, showOverflow: false, minWidth: 90 },{ title: '省略号', field: 'bb', formType: 'input', sortable: true, showOverflowTooltip: true, width: 110 },{ title: '年月日', field: 'cc', formType: 'daterange', sortable: true, dateType: 'YYYY-MM-DD', width: 120 },{ title: '年月日时分秒', field: 'dd', formType: 'datetimerange', sortable: true, dateType: 'YYYY-MM-DD HH:mm:ss', width: 150 },{title: '单选', field: 'ee', formType: 'select', sortable: true, selectList: nameList, width: 100,slots: {default: ({ row }) => {const val = nameList.value.find(item => item.value === row.ee)?.name || ''return [<span>{val}</span>]},}},{title: '下拉多选', field: 'ff', formType: 'selectMultiple', sortable: true, selectList: [], requestData: { businessCode: '自定义接口参数' }, minWidth: 120,},{title: '遍历多选', field: 'faf', formType: 'selectMultiple', sortable: true, selectList: moreList.value, showOverflow: false, width:120,slots: {default: ({ row }) => {let dom = []let arr = row.faf || []arr.forEach(ele => {dom.push(<div style={{ height: '24px' }}>{filters(ele, moreList.value) || ''}</div>)})return dom},}},{title: '多选远程搜索', field: 'orgId', formType: 'selectMultipleRemote', selectList: [], requestData: { businessCode: 'DEVICE_TABLE' }, minWidth: 120,slots: {default: ({ row }) => {return [<span>中文名称{row.orgId}</span>]},}},{title: '点击事件', field: 'hh', formType: 'input', sortable: true, minWidth: 120,slots: {default: ({ row, column }) => {return [<span style="cursor: pointer;color:#11716f;text-decoration: underline;" onClick={() => clickItem(row, 'view', column)}> {row.hh} {column.field}</span>]},}},{title: '枚举', field: 'ii', formType: 'select', sortable: true, minWidth: 100, selectList: [{ name: '已反馈', value: 1 },{ name: '未反馈', value: 0 },],slots: {default: ({ row }) => (row ? <el-tag style="border: none;" class="cursor" type={row.ii === 1 ? 'primary' : 'warning'}>{row.ii === 1 ? '已反馈' : row.ii === 0 ? '未反馈' : ''}</el-tag> : ''),}},{title: '查询默认值', field: 'jj', formType: 'input', minWidth: 110, defaultValue: '123',},{title: '隐藏列', field: 'kk', minWidth: 100, visible: false,},{title: '操作', field: 'actionBtn', width: 160, fixed: 'right',slots: {default: ({ row }) => ([<el-button link type="primary" size="small" onClick={() => editItem(row, 'edit')} >编辑</el-button >,<el-divider direction="vertical" />,<el-button link type="primary" size="small" onClick={() => editItem(row, 'view')} >查看</el-button >,<el-divider direction="vertical" />,<el-button link type="danger" size="small" onClick={() => editItem(row, 'delete')} >删除</el-button >,])}},],
})let totalNum = ref(100)
let queryForm = ref({})
// 函数
const searchList = (item) => {console.log('%c【' + 'item' + '】打印', 'color: red;background:#0f0', item)
}
// 函数
const getList = (item) => {console.log('%c【' + 'item' + '】打印', 'color: red;background:#0f0', item)
}
let tableData = Array.from({ length: 10 }).map((ele, index) => {return {aa: '长文本换行' + index,bb: '长文本隐藏隐藏隐藏隐藏隐藏',cc: '2023-7-20',dd: '2023-7-20 10:10:10',ee: Math.floor(Math.random() * 5),ff: [1, 2],faf: [1, 2],gg: '中文',hh: Math.floor(Math.random() * 20),ii: Math.floor(Math.random() * 2),jj: index,kk: index,}
})let formEditLoading = ref(false) // 表单loading
// 上线申请表单
const formInfo = ref(null)
// 上线弹框显示
let dialogItemObj = ref({dialogVisible: false,title: '',dataForm: {},formType: 'add'
})
// 点击事件
const clickItem = (row, type, column) => {console.log(row, type, column);ElMessage({type: 'success',message: '点击',})
}
// 编辑或查看
const editItem = (row, type) => {dialogItemObj.value.formType = type// console.log(row, type); switch (type) {case 'edit':dialogItemObj.value.dialogVisible = truedialogItemObj.value.title = '编辑'dialogItemObj.value.dataForm = { ...row }break;case 'view':dialogItemObj.value.dialogVisible = truedialogItemObj.value.title = '查看'dialogItemObj.value.dataForm = { ...row }break;case 'delete':deleteItem(row, type)break;default:break;}
}
// 删除
const deleteItem = (row,) => {ElMessageBox.confirm("确定要删除该条数据信息吗?", "删除", {confirmButtonText: "确认",cancelButtonText: "取消",showClose: false,closeOnClickModal: false}).then(async () => {await delRuleConfig({ id: row.id })getList()ElMessage.success(`删除成功!`)})
}
// 创建应用申请
const submitApp = () => {let requestApi = operateRuleConfigformEditLoading.value = trueformInfo.value.getValidateData((data) => {// console.log('子组件返回参数', data);if (data) {requestApi({ ...data }).then(() => {let msg = dialogItemObj.value.formType === 'add' ? '新增成功' : '编辑成功'ElMessage.success(msg)dialogItemObj.value.dialogVisible = falsegetList()}).finally(() => {formEditLoading.value = false})} else {formEditLoading.value = false}})
}
// 清空
const resetApplication = () => {formInfo.value.resetForm(() => {dialogItemObj.value.dialogVisible = false})
}// 拿到搜索条件
const searchEvent = (data) => {let newList = replaceStr(['orgId',], ['orgIdList',], { ...queryForm.value, ...data })queryForm.value = newListsearchList()
}
// 多选
const checkboxEvent = (data) => {console.log('checkboxEvent', data);
}
// 单选
const radioEvent = (data) => {console.log('radioEvent', data);
}
onMounted(() => {setTimeout(() => {nameList.value = [{ name: '横向隔离', value: 0 },{ name: '纵向加密', value: 1 },{ name: '防火墙', value: 2 },{ name: '监测装置', value: 3 },{ name: '运维网关', value: 4 },{ name: '其他', value: 5 },]}, 1000);
})
</script><style lang="scss" scoped></style>
2.@/utils/filter.js
一般用不到这几个方法,我是特殊处理获取配置表单的默认值和接口传参处理key用的
// 下拉过滤回显
export const filters = (key, arr = []) => {const names = []const value = Array.isArray(key) ? key : [key]for (let i = 0; i < arr.length; i++) {if (value.includes(arr[i].value)) {names.push(arr[i].name)}}return names.join(";")
}// 拿到表格默认结构里的搜索默认值
export const getDefaultValue = columns => {let searchObj = {inputList: {},selectList: {},dateList: {}}columns.forEach(ele => {if (ele.field && ele.formType) {// if (ele.formType === 'input') {// searchObj['inputList'][ele.field] = ele.defaultValue || undefined// } else if (ele.formType === 'select' || ele.formType === 'selectMultiple' || ele.formType === 'selectMultipleRemote') {// searchObj['selectList'][ele.field] = ele.defaultValue || undefined// } else if (ele.formType === 'daterange' || ele.formType === 'datetimerange') {// searchObj['dateList'][ele.field] = ele.defaultValue || undefined// } else {// searchObj[ele.field] = ele.defaultValue || undefined// }searchObj[ele.field] = ele.defaultValue || undefined}})return searchObj
}// 拿到表头组件的搜索默认值
export const getSearchValue = (columns, data) => {let searchObj = {inputList: {},selectList: {},dateList: {}}columns.forEach(ele => {if (ele.field && ele.formType) {if (ele.formType === "input") {searchObj["inputList"][ele.field] = data[ele.field] || undefined} else if (ele.formType === "select" || ele.formType === "selectMultiple" || ele.formType === "selectMultipleRemote") {searchObj["selectList"][ele.field] = data[ele.field] || undefined} else if (ele.formType === "daterange" || ele.formType === "datetimerange") {searchObj["dateList"][ele.field] = data[ele.field] || undefined} else {searchObj[ele.field] = data[ele.field] || undefined}}})return searchObj
}// 暂时替换字段
export const replaceStr = (arr1, arr2, obj) => {// 创建一个新的对象,避免直接修改原始对象const newObj = { ...obj }// 遍历 arr1 并替换 newObj 中的相应属性名arr1.forEach((key, index) => {if (key in newObj) {// 用 arr2 中的对应值替换属性名newObj[arr2[index]] = newObj[key]// 删除旧的属性名delete newObj[key]}})return newObj
}