技术标签: vxe-table 前端 vue.js javascript
表格数据过多时,需要过滤数据
代码:
// 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 类型过滤
一、问题概述大家都玩过棋盘游戏吧,像五子棋一样,玩家或者是电脑一人下一次,当玩家或者是电脑的某一方先将各自的五个棋子下成一条线时,谁就赢,棋盘游戏就会结束。 当然,我今天要介绍的是三子棋,和五子棋的原理是一样的,当玩家或者是电脑的某一方先将各自的三个棋子下成一条线时,谁就赢,棋盘游戏就会结束。下面我们用如下棋盘模拟一下电脑上的棋盘
写在前面一年一度的春运即将来临,各位看官回家的票有没有买好呢?反正小编已经按捺不住激动的心情,开始蠢蠢欲动了。但是作为技术控,就应该有技术控的抢票姿态,鉴于12306逆天的验证码,小编放弃了控制12306自动抢票的骚操作,开始走向自动余票提醒:有余票=>微信推送余票信息的道路。学习Python过程中会遇到很多问题,可以到我们的 python学习交流群【六 五 三,四...
解决方法:将软件安装到U盘 1.接入U盘 #确认挂载df -h#创建使用的目录mkdir /mnt/sda1/openwrt 2.修改/etc/opkg.conf ]# vim /etc/opkg.confdest root /dest usb /mnt/sd...
文章目录一、大数定律1.1 贝努力大数定律(伯努利)1.2 切比雪夫大数定律一、大数定律切比雪夫不等式—大数定律的引理 设 XXX 为一个随机变量,E(X),D(X)E(X),D(X)E(X),D(X) 存在,则对 ∀a>0\forall{a}>0∀a>0,有P(∣X−E(X)∣≥a)≤D(X)a2P(|X-E(X)| \geq a) \leq \frac{D(X)}{a^2}P(∣X−E(X)∣≥a)≤a2D(X)或P(∣X−E(X)∣≤a)≥1−D(X)a2P(
TestNG源码解析2——测试用例实例化过程本文介绍执行用例前如何将XmlSuite实例化测试类的过程<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd"><suite name="SuiteA"> <!--XmlSuite--> <listeners> <listener class
转载自此文 https://www.jianshu.com/p/bce9077d883c通过此文的指导顺利的完成了Jmeter在mac下的安装,因为之前在windows使用过jmeter所以对流程比较熟悉。这里把遇到的一些坑,怎么解决的附上1、首先是下载JDK版本的时候,JDK版本很可能已经发生了变化,下载的JDK版本是与链接不一样的,这个需要注意。下载的时候会提示 accept l...
需求:日期范围选择器,当选择好一个日期范围时,立即触发查询功能<el-date-picker v-model="dateVal" type="daterange" size="small" format="yyyy 年 MM 月 dd 日" value-format="yyyy-MM-dd HH:mm:ss" range-s...
引言上周有个小伙伴问我有没有个人博客,想和我互换一个友链。我以前也想过要自己搭个博客,但是一直迟迟没有行动,一般写了文章就往其他平台发一下就完事了。想了想为啥自己没有搭建一个属于自己的博客?一来的话可能嫌麻烦,需要往自己的博客平台发布,平时一些第三方博客平台的话都懒得发了,二来的话还要买服务器和域名一般的配置一年也得几百大洋。所以一直没有搭建一个属于自己的博客。但是现在作为一个自媒体的时代,许多程序员都拥有自己的博客或者个人网站,这类站点的建立可以帮助我们记录生活点滴,进行个人展示,也能帮助自己扩...
算法提高 递归倒置字符数组时间限制:1.0s 内存限制:512.0MB问题描述 完成一个递归程序,倒置字符数组。并打印实现过程 递归逻辑为: 当字符长度等于1时,直接返回 否则,调换首尾两个字符,在递归地倒置字符数组的剩下部分输入格式 字符数组长度及该数组输出格式 在求解过程中,打印字符数组的变化情况。 最后空一行,在程序结尾处打印倒置后该数组的各个元素。...
1.什么是蒙特卡洛方法(Monte Carlo method)蒙特卡罗方法也称统计模拟方法,是1940年代中期由于科学技术的发展和电子计算机的发明,而提出的一种以概率统计理论为指导的数值计算方法。是指使用随机数(或更常见的伪随机数)来解决很多计算问题的方法。 20世纪40年代,在冯·诺伊曼,斯塔尼斯拉夫·乌拉姆和尼古拉斯·梅特罗波利斯在洛斯阿拉莫斯国家实验室为核武器计划工作时,发明了蒙特卡罗...
一、数据准备import pandas as pd data = pd.read_excel(r'测试.xlsx')print(data) 如下数据 名称 类型 型号 C0 多多 1 AA 121 多多1 2 BB 12# 使用del, 一次只能删除一列,不能一次删除多列import pandas as pddata = pd.read_excel(r'测试.xlsx')print(d
本篇将介绍使用OpenCV来缩放图片。首先介绍几个关键函数——cvResize和cvCreateImage一. 主要函数介绍1.1 cvResize函数功能:图像大小变换函数原型:voidcvResize( const CvArr* src, CvArr* dst, intinterpolation=CV_INTER_LINEAR);函数说明: