vue动态表格以及搜索内容高亮显示

展示效果

在这里插入图片描述

需求

表格根据后端返回的数据,动态展示行和列
输入搜索内容后,对对应的文本进行高亮显示
左侧可以筛选要展示的列

实现

表格样式

<!--      头部-->
<div style="background: #f3f6fb">
  <template v-for="(item, index) in listHeader.list">
    <div
      :key="index"
      class="table-content table-title-container"
      :title="listHeader.title[index]"
      :style="{ width: `${changeWidth(item) ? changeWidth(item) : headerWidth}` }"
    >
      <div style="display: inline-block">{{ item }}</div>
      <div
        @click="sortList(item)"
        style="
          display: inline-block;
          position: relative;
          width: 10px;
          height: 10px;
          cursor: pointer;
        "
        v-if="item.indexOf('timestamp') !== -1 || item.indexOf('timeStamp') !== -1"
      >
        <svg-icon class="table-title-svg" icon-class="topic-sort"></svg-icon>
      </div>
    </div>
  </template>
</div>
<!--      表格内容-->
<template v-for="(item, index) in searchList.list">
  <div class="line-content" :key="index + '-'" v-if="Object.entries(item).length > 0">
    <div class="line-height" :style="{ width: `${listWidth + 'px'}` }">
      <template v-for="(item1, index1) in listHeader.list">
        <div
          :key="index1"
          class="table-content"
          :style="{ width: `${changeWidth(item1) ? changeWidth(item1) : headerWidth}` }"
        >
          <div
            class="table-newline"
            v-if="item1.indexOf('timestamp') !== -1 || item1.indexOf('timeStamp') !== -1"
            style="color: #3096ff"
            v-html="switchPosition(item, item1)"
          />
          <div class="table-newline" v-else v-html="switchPosition(item, item1)"></div>
        </div>
      </template>
    </div>
    <a-divider class="table-divider" :style="{ width: `${listWidth + 'px'}` }"></a-divider>
  </div>
</template>

css样式

.table-content {
  text-align: center;
  position: relative;
  display: inline-block;
}
.table-title-container {
  background: #f3f6fb;
  padding: 10px 0;
}
.table-title-svg {
  width: 16px;
  height: 16px;
  position: absolute;
  left: 0;
}
.line-content {
  max-height: 401px;
  margin: 5px 0;
}
.line-height {
  max-height: 400px;
  overflow-y: auto;
  overflow-x: hidden;
}
.table-newline {
  padding: 8px 8px;
  height: 95%;
  display: flex;
  flex-direction: column;
  word-break: break-word;
  white-space: normal;
}
.table-divider {
  margin: 5px 0;
}

表格内容排列

switchPosition(value, header) {
 let res = '--';
 Object.entries(value).forEach((item) => {
   if (item[0] === header) {
     res = item[1];
   } else if (item[1] && typeof item[1] === 'object') {
     Object.entries(item[1]).forEach((items) => {
       if (items[0] === header) {
         res = items[1];
       }
     });
   }
 });
 if (res != null) {
   return this.brightenKeyword(res, this.content);
 } else return '--';
},
changeWidth(value) {
 if (this.listWidth === this.screenWidth) {
   this.headerWidth = (this.screenWidth - this.width) / this.length + 'px';
 } else {
   return value.length * 10 + 'px';
 }
},

表格搜索高亮

//搜索高亮
brightenKeyword(val, keyword) {
  if (
    Object.prototype.toString.call(val) !== '[object Array]' &&
    Object.prototype.toString.call(val) !== '[object Object]'
  ) {
    return this.replaceWord(val, keyword);
  } else if (
    Object.prototype.toString.call(val) === '[object Array]' ||
    Object.prototype.toString.call(val) === '[object Object]'
  ) {
    return this.replaceWord(JSON.stringify(val), keyword);
  } else return val;
},
replaceWord(val, keyword) {
  val = val + '';
  if (val.indexOf(keyword) !== -1 && keyword !== '') {
    //关键词替换
    val = val.replace(
      new RegExp(keyword, 'g'),
      '<span style="background-color: #FFAD0F">' + keyword + '</span>'
    );
    //解决文字换行问题
    val = '<span>' + val.replace(/\n/g, '</span> <span>') + '</span>';
    return val;
  } else return val;
},

数据格式处理

后端返回的数据格式

this.searchList = {
	"_hik_ingest_timestamp":"2021-08-13T07:25:31.545045Z",
	"brake_system_status":{
		"brake_padel":1
	}
	"exterior_lights":{
		"all_lights_off":0,
		"automatic_light_control":0,
		"daytime_running_lights":0,
		"fog_lights":0,
		"high_beam_head_lights":0
	}
	"motion":{
		"speed":22.222222
	}
	"obuEsn":"27567864",
	"obuId":"obu_123"
}

解析json格式

生成表头和对应内容

this.searchList.forEach((item) => {
 Object.entries(item).forEach((items) => {
   if (items[1] && Object.prototype.toString.call(items[1]) === '[object Object]') {
     Object.entries(items[1]).forEach((item1) => {
       if (this.listHeader.list.indexOf(item1[0]) === -1) {
         this.listHeader.list.push(item1[0]);
         this.listHeader.title.push(items[0] + '.' + item1[0]);
       }
     });
   } else if (this.listHeader.list.indexOf(items[0]) === -1) {
     this.listHeader.list.push(items[0]);
     this.listHeader.title.push(items[0]);
   }
 });
});

表头字段筛选功能

//增加选定字段
 pushField(item) {
   this.chooseField.push(item);
   this.fieldList.splice(this.fieldList.indexOf(item), 1);
   this.queryParams.fields.push(item.fieldName);
   this.getSearchList();
   this.onSearch();
 },
 //删除选定字段
 popField(item) {
   this.fieldList.push(item);
   this.chooseField.splice(this.chooseField.indexOf(item), 1);
   this.queryParams.fields.splice(this.queryParams.fields.indexOf(item.fieldName), 1);
   this.getSearchList();
   this.onSearch();
 },
 //字段搜索
 onSearch() {
   if (this.field) {
     let newArr = [],
       chooseArr = [];
     this.fieldList.forEach((item) => {
       if (item.fieldName.indexOf(this.field) !== -1) {
         newArr.push(item);
       }
     });
     this.searchFieldList = newArr;
     this.chooseField.forEach((item) => {
       if (item.fieldName.indexOf(this.field) !== -1) {
         chooseArr.push(item);
       }
     });
     this.searchChooseField = chooseArr;
   } else {
     this.searchFieldList = this.fieldList;
     this.searchChooseField = this.chooseField;
   }
 },
  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值