一步步实现一个简单的适用于iview的vue表格搜索组件,支持下拉选择指定列进行搜索

最近在使用vue+iview做一个后台管理系统,在做表格部分时发现iview的表格并不支持搜索,不过iview易于拓展,可以很方便的拓展出表格搜索功能,比如在iview-admin就存在可搜索表格,但是功能比较基础,而且没有封装为单独组件,接下来我们就一步步的实现一个支持下拉选择指定列进行搜索的表格搜索组件。完整代码:https://github.com/shawpo/vue-iview-tableSearch


首先我们可以来看下iview-admin表格搜索的实现,以示例中按姓名搜索为例,其实现实现了按姓名搜索。

// 关键代码
<template>
......
  <Input 
      v-model="searchConName1" 
      icon="search" 
      @on-change="handleSearch1" 
      placeholder="请输入姓名搜索..." 
      style="width: 200px" 
  />
......
</template>
<script>
......
export default {
......
    methods: {
        ......
        search (data, argumentObj) {
            let res = data;
            let dataClone = data;
            for (let argu in argumentObj) {
                if (argumentObj[argu].length > 0) {
                    res = dataClone.filter(d => {
                        return d[argu].indexOf(argumentObj[argu]) > -1;
                    });
                    dataClone = res;
                }
            }
            return res;
        },
        handleSearch1 () {
            this.data1 = this.initTable1;
            this.data1 = this.search(this.data1, {name: this.searchConName1});
        },
        ......
    },
    ......
};
</script>
  • 首先简单说明下这个示例的实现流程:将input输出框的on-change事件与组件的handleSearch1方法绑定,在输入框内容发生变化时运行handleSearch1 方法。而handleSearch1方法则将表格的初始数据数据(this.data1)与搜索条件对象(将搜索列与搜索内容拼装成对象形式后)传递给search方法执行搜索,并将表格数据设置search方法返回搜索结果。
  • 接下来是代码的说明,从handleSearch1方法开始,其首先将原始的表格数据赋值给data1,以保障每次搜索都是从原始表格数据中搜索,将搜索列与搜索内容拼装成对象形式作为搜索条件,将然后将data1以及搜索条件对象传递给search方法,这里的'name'为表格数据中对应列内容的字段名。接下来就是重要的search方法了,可以看出这个方法是支持多条件(多列)搜索的,其首先对搜索条件对象进行了遍历,当对象的一个属性的值不没空时(则说明这个属性可以作为搜索的一个条件),通过函数filter对dataClone进行过滤,并将过滤结果赋值给dataClone以用于下一个循环,循环完毕后,所有的搜索条件都执行完毕,dataClone即为搜索结果,将其返回即可。

接下来我们就对这个简单的搜索进行拓展以支持下拉选择指定列进行搜索并封装为单独组件,想要支持这一功能,我们首先需要列名以及表格数据中对应列内容的字段名等信息,而创建iview表格的所需的列配置参数(columns)中就包含这些信息,因此可以很方便的开发出适用于iview表格的搜索组件。

<Input
    placeholder="请选择列名并输入内容..."
    v-model="searchContent"
    @on-change="handleSearch">
    <Select slot="prepend" style="width: 80px" v-model="searchColumn">
        <Option
          v-for="column in searchColumns"
          :value="column.key"
          :key="column.key">
          {{column.title}}
        </Option>
    </Select>
</Input>
  • 完成了UI部分之后就需要为UI提供数据完成数据绑定,首先是为下拉选择器提供数据
    同样非常简单,父组件使用时将iview表格的columns参数对应的对象数组(父组件可对数组进行处理,过滤不需要支持搜索的列)传递过来即可。
// 关键代码
......
<table-search
   ......
   :searchColumns="searchColumns"
   >
</table-search>

......
computed: {
  searchColumns: function () {
    // 过滤不需要支持搜索的列,这里过滤掉了“状态”列
    return this.menusColumns.filter( (d) => {
      return d['key'] && d['key'] != 'status'
    })
  }
},
......
  • 表格数据
    要实现搜索,当然需要表格数据,与上面iview-admin的示例不同的是,我们将表单搜索封装成了单独组件,因此我们需要从父组件获取表格数据,并在完成搜索之后,将父组件的表格数据更新为搜索结果的数据。我们可以很容易的想到:使用.sync修饰符从父组件中将表格数据传递过来,像上面一样克隆数据,执行搜索,然后通过触发事件将父组件的表格数据更新为搜索结果的数据即可。没错,确实是这样的,整个流程很简单,但是这里存在一个问题,父组件的表格数据通常是从服务器中获取的,存在异步操作。我们需要当服务器端完成异步操作之后再对其进行克隆,否则若克隆的表格数据为空,无论如何搜索得到值都为空。
// 父组件
<table-search
  :tableData.sync="menusData"
  :searchColumns="searchColumns"
  >
</table-search>
watch: {
     // 因父组件表格数据通常存在异步操作
     // 需监听props以得到正确的数据
     tableData: function (newTableData) {
       if (newTableData.length > 0 && this.tableDataClone.length == 0) {
         this.tableDataClone = newTableData
       }
     }
}
  • 执行搜索
    这一过程与iview-admin的示例非常相似,不同的是要执行搜索的列来自于用户在下拉选择中的输入,因此我们需要获取用户输入并将其处理为搜索条件对象传递给search方法执行搜索,而搜索完成后我们需要更新父组件表格数据。
 methods: {
      // 表格搜索函数,可支持多列搜索
      search: function (data, argumentObj) {
        let res = data;
        let dataClone = data;
        for (let argu in argumentObj) {
          if (argumentObj[argu].length > 0) {
            res = dataClone.filter(d => {
              return d[argu].indexOf(argumentObj[argu]) > -1;
            });
            dataClone = res;
          }
        }
        return res;
      },
      handleSearch: function () {
        var argumentObjStr = '{"' + this.searchColumn + '": "' + this.searchContent + '"}' // 拼接json
        var argumentObj = JSON.parse(argumentObjStr) // 转为对象
        var res = this.search(this.tableDataClone, argumentObj) // 执行搜索,获取搜索结果
        this.$emit('update:tableData', res) // 更新表格数据为搜索结果
      }
},

结束

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,723评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,080评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,604评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,440评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,431评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,499评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,893评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,541评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,751评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,547评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,619评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,320评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,890评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,896评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,137评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,796评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,335评论 2 342

推荐阅读更多精彩内容