vxe-grid筛选渲染
vxe-grid筛选渲染表格数据过多时,需要过滤数据代码:// index.vue<template><div style="height: 400px"><vxe-grid ref="xGrid" v-bind="gridOptions"></vxe-grid></div></template><script>e
·
vxe-grid筛选渲染
表格数据过多时,需要过滤数据
代码:
// index.vue
<template>
<div style="height: 400px">
<vxe-grid ref="xGrid" v-bind="gridOptions"></vxe-grid>
</div>
</template>
<script>
export default {
data () {
return {
gridOptions: {
highlightHoverRow: true,
autoResize: true,
height: 'auto',
border: true,
loading: false,
editConfig: {
trigger: 'dblclick',
mode: 'cell',
showStatus: true,
showIcon: false,
activeMethod: this.activeCellMethod
},
mouseConfig: {
selected: true,
area: true,
extension: true
},
columns: [
{ type: 'seq' },
{
field: 'name',
title: 'Name',
filters: [{ data: '' }],
filterRender: { name: 'FilterInput' }
},
{
field: 'role',
title: 'Role',
editRender: { name: 'RoleCell', events: { click: this.getCellData } },
filters: [{ data: { vals: [], sVal: '' } }],
filterRender: {
name: 'FilterContent'
}
},
{ field: 'sex', title: 'Sex' },
{
field: 'age',
title: '年龄',
filters: [{ data: { type: 'lt', name: '' } }],
filterRender: { name: 'FilterComplex' }
}
],
data: []
}
}
},
mounted () {
this.getData().then((data) => {
this.gridOptions.data = data
})
},
methods: {
activeCellMethod () {
return true
},
getCellData (params) {
console.log(params)
},
getData () {
return new Promise((resolve) => {
const list = [
{ name: 'Test1', role: '前端', sex: '男', age: 13 },
{ name: 'Test2', role: '后端', sex: '男', age: 11 },
{ name: 'Test3', role: '测试', sex: '男', age: 15 },
{ name: 'Test4', role: '设计师', sex: '女', age: 12 },
{ name: 'Test5', role: '前端', sex: '男', age: 13 },
{ name: 'Test6', role: '前端', sex: '男', age: 16 },
{ name: 'Test7', role: '前端', sex: '男', age: 22 }
]
resolve(list)
})
}
}
}
</script>
// table.js 定义组件
VXETable.renderer.add('FilterContent', {
// 不显示底部按钮,使用自定义的按钮
isFooter: false,
// 筛选模板
renderFilter (h, renderOpts, params) {
return [
<filter-content params={ params }></filter-content>
]
},
// 重置数据方法
filterResetMethod ({ options }) {
options.forEach(option => {
option.data = { vals: [], sVal: '' }
})
},
// 筛选数据方法
filterMethod ({ option, row, column }) {
const { vals } = option.data
console.log(vals)
// eslint-disable-next-line no-undef
let cellValue = XEUtils.get(row, column.property)
if (column.property === 'customerItemCode') {
cellValue = cellValue.customerItemCode || cellValue
}
return vals.includes(cellValue)
}
})
// 条件过滤
VXETable.renderer.add('FilterComplex', {
// 不显示底部按钮,使用自定义的按钮
isFooter: false,
// 筛选模板
renderFilter (h, renderOpts, params) {
const { events } = renderOpts
return [
<filter-complex params={ params } events={events}></filter-complex>
]
},
// 重置数据方法
filterResetMethod ({ options }) {
// console.log(options)
options.forEach(option => {
option.data = { type: 'lt', name: '' }
})
},
// 筛选数据方法
filterMethod ({ option, row, column }) {
// console.log(option, row, column)
const cellValue = parseFloat(XEUtils.get(row, column.property))
// console.log(cellValue)
const { name, type } = option.data
if (!name) {
return true
}
if (type === 'lt') {
return cellValue < parseInt(name)
} else if (type === 'eq') {
return cellValue === parseInt(name)
} else if (type === 'gt') {
return cellValue > parseInt(name)
}
return false
}
})
VXETable.renderer.add('FilterInput', {
// 筛选模板
renderFilter (h, renderOpts, params) {
// console.log(params)
return [
<filter-input params={ params }></filter-input>
]
},
// 筛选方法
filterMethod ({ option, row, column }) {
const { data } = option
const cellValue = row[column.property]
if (cellValue) {
return cellValue.indexOf(data) > -1
}
return false
}
})
// 内置组件 FilterContent.vue
<template>
<div class="my-filter-content">
<div class="my-fc-search">
<div class="my-fc-search-top">
<vxe-input v-model="option.data.sVal" placeholder="搜索" @input="searchEvent" suffix-icon="fa fa-search"></vxe-input>
</div>
<div class="my-fc-search-content">
<template v-if="valList.length">
<ul class="my-fc-search-list my-fc-search-list-head">
<li class="my-fc-search-item">
<vxe-checkbox v-model="isAll" @change="changeAllEvent">全选</vxe-checkbox>
</li>
</ul>
<ul class="my-fc-search-list my-fc-search-list-body">
<li class="my-fc-search-item" v-for="(item, sIndex) in valList" :key="sIndex">
<vxe-checkbox v-model="item.checked">{{ item.value }}</vxe-checkbox>
</li>
</ul>
</template>
<template v-else>
<div class="my-fc-search-empty">无匹配项</div>
</template>
</div>
</div>
<div class="my-fc-footer" style="text-align: right">
<vxe-button type="text" @click="confirmFilterEvent">筛选</vxe-button>
<vxe-button style="margin-left: 0" type="text" @click="resetFilterEvent">重置</vxe-button>
</div>
</div>
</template>
<script>
import XEUtils from 'xe-utils'
export default {
name: 'FilterContent',
props: {
params: Object
},
data () {
return {
size: 'mini',
isAll: false,
option: null,
colValList: [],
valList: []
}
},
created () {
this.load()
},
methods: {
load () {
const { $table, column } = this.params
const { fullData } = $table.getTableData()
const option = column.filters[0]
const { vals } = option.data
let colValList = Object.keys(XEUtils.groupBy(fullData, column.property)).map(val => {
return {
checked: vals.includes(val),
value: val
}
})
const columnsArr = []
console.log(XEUtils.groupBy(fullData, column.property))
if (column.property === 'customerItemCode') {
fullData.forEach(item => {
// console.log(item['customerItemCode']['customerItemCode'])
const toValue = item.customerItemCode.customerItemCode
if (toValue) {
columnsArr.push({
checked: vals.includes(toValue),
value: toValue
})
}
})
if (columnsArr && columnsArr.length) {
colValList = columnsArr
}
}
console.log(colValList)
this.option = option
this.colValList = colValList
this.valList = colValList
},
searchEvent () {
const { option, colValList } = this
this.valList = option.data.sVal ? colValList.filter(item => item.value.indexOf(option.data.sVal) > -1) : colValList
},
changeAllEvent () {
const { isAll } = this
this.valList.forEach(item => {
item.checked = isAll
})
},
confirmFilterEvent (evnt) {
const { params, option, valList } = this
const { data } = option
const { $panel } = params
data.vals = valList.filter(item => item.checked).map(item => item.value)
console.log(this.events)
$panel.changeOption(evnt, true, option)
$panel.confirmFilter()
},
resetFilterEvent () {
const { $panel } = this.params
$panel.resetFilter()
}
}
}
</script>
<style>
.my-filter-content {
padding: 10px;
user-select: none;
}
.my-filter-content .my-fc-search .my-fc-search-top {
position: relative;
padding: 5px 0;
}
.my-filter-content .my-fc-search .my-fc-search-top > input {
border: 1px solid #ABABAB;
padding: 0 20px 0 2px;
width: 200px;
height: 22px;
line-height: 22px;
}
.my-filter-content .my-fc-search .my-fc-search-content {
padding: 2px 10px;
}
.my-filter-content .my-fc-search-empty {
text-align: center;
padding: 20px 0;
}
.my-filter-content .my-fc-search-list {
margin: 0;
padding: 0;
list-style: none;
}
.my-filter-content .my-fc-search-list-body {
overflow: auto;
height: 120px;
}
.my-filter-content .my-fc-search-list .my-fc-search-item {
padding: 2px 0;
display: block;
}
.my-filter-content .my-fc-footer {
text-align: right;
padding-top: 10px;
}
.my-filter-content .my-fc-footer button {
/* padding: 0 15px; */
/* margin-left: 15px; */
}
.my-fc-search-content ul {
text-align: left;
}
</style>
条件搜索过滤
// FilterInput.vue
<template>
<div class="my-filter-input" style="text-align: right">
<vxe-input type="text" v-model="option.data" placeholder="支持回车筛选" @keyup="keyupEvent" @input="changeOptionEvent"></vxe-input>
</div>
</template>
<script>
export default {
name: 'FilterInput',
props: {
params: Object
},
data () {
return {
column: null,
option: null
}
},
created () {
this.load()
},
methods: {
load () {
const { column } = this.params
const option = column.filters[0]
this.column = column
this.option = option
},
changeOptionEvent () {
// console.log('输入')
const { params, option } = this
const { $panel } = params
const checked = !!option.data
$panel.changeOption(null, checked, option)
},
keyupEvent ({ $event }) {
const { params } = this
const { $panel } = params
if ($event.keyCode === 13) {
$panel.confirmFilter()
}
}
}
}
</script>
<style scoped>
.my-filter-input {
padding: 10px;
}
</style>
文本搜索过滤
// FilterComplex.vue
<template>
<div class="my-filter-complex">
<div class="my-fc-type">
<vxe-radio v-model="option.data.type" name="fType" label="lt">小于</vxe-radio>
<vxe-radio v-model="option.data.type" name="fType" label="eq">等于</vxe-radio>
<vxe-radio v-model="option.data.type" name="fType" label="gt">大于</vxe-radio>
</div>
<div class="my-fc-name">
<vxe-input v-model="option.data.name" type="text" placeholder="请输入数量" @input="changeOptionEvent()"></vxe-input>
</div>
<div class="my-fc-footer" style="text-align: right">
<vxe-button :disabled="!option.data.name" type="text" @click="confirmEvent">筛选</vxe-button>
<vxe-button style="margin-left: 0" type="text" @click="resetEvent">重置</vxe-button>
</div>
</div>
</template>
<script>
// import XEUtils from 'xe-utils'
export default {
name: 'FilterComplex',
props: {
params: Object,
events: Object
},
data () {
return {
size: 'mini', // 被所有子组件继承 size
column: null,
option: null
}
},
created () {
this.load()
},
methods: {
load () {
const { column } = this.params
console.log(this.params)
const option = column.filters[0]
this.column = column
this.option = option
},
changeOptionEvent () {
console.log('输入')
const { params, option } = this
const { $panel } = params
const checked = !!option.data.name
$panel.changeOption(null, checked, option)
},
confirmEvent () {
console.log(this.params)
const { $panel, column } = this.params
console.log(column)
$panel.confirmFilter()
},
resetEvent () {
// eslint-disable-next-line no-unused-vars
const { $panel } = this.params
$panel.resetFilter()
}
}
}
</script>
<style scoped>
.my-filter-complex {
width: 260px;
padding: 5px 15px 10px 15px;
}
.my-filter-complex .my-fc-type {
padding: 8px 0;
}
.my-filter-complex .my-fc-footer {
text-align: center;
}
</style>
Number 类型过滤
更多推荐
已为社区贡献10条内容
所有评论(0)