el-tree目录和el-table实现搜索定位高亮方法

22 篇文章 0 订阅
14 篇文章 0 订阅

需求:el-tree目录实现搜索查询el-table表格项,双击表格项根据yiZhuMLID||muLuID定位el-tree目录,并且高亮展示在可视化区域内,再重新根据el-tree目录的yiZhuMLID搜索刷新el-table表格,定位且高亮展示相对应的yiZhuMLID的需求

1、先上DOM代码

    <div class="main">
      <div class="left">
        <el-tree
          ref="tree"
          class="tree"
          :data="labWorkOptions"
          :props="defaultProps"
          node-key="yiZhuMLID"
          :default-expanded-keys="currentNodekey"
          highlight-current
          @node-click="handleNodeClick"
        />
      </div>
      <div class="center">
        // 封装的el-table(后面加上)
        <PublicTable
          ref="multipleTable"
          row-key="$multipleTable"
          class="table"
          :is-need-pagination="false"
          :table-data="centerTableData"
          :table-info="tableInfo"
          :need-select="true"
          :table-column="centerColumns"
          :events="centerEvents"
          :has-operation="false"
        />
        <div class="centerSearch">
          <el-input
            v-model="queryString"
            class=""
            size="small"
            clearable
            placeholder="请输入格式拼音/五笔首码搜索"
            @clear="onSearch"
            @keyup.enter.native="onSearch"
          />
          <el-button
            size="small"
            class="el-button-color"
            style="margin-right: 10px"
            icon="el-icon-search"
            @click="onSearch"
          >
            查询
          </el-button>
        </div>
      </div>
      <div class="right">
        <PublicTable
          ref="publicTable"
          class="table"
          :is-need-pagination="false"
          :table-data="rightData"
          :table-info="tableInfo"
          :table-column="rightColumns"
          :has-operation="false"
        />
      </div>
    </div>

2、样式Style代码

<style lang="scss" scoped>
::v-deep .el-table__body-wrapper {
  overflow: auto;
}
.title {
  font-size: 15px;
  font-weight: 600;
  padding: 0 8px;
  border-left: 3px solid #21c5c8;
}
.main {
  display: flex;
  width: 100%;
  height: 100%;
  .left {
    flex: 1;
    max-width: 25%;
    overflow: auto;
    ::v-deep .tree {
      height: 500px;
    }
  }
  .center {
    max-width: 29%;
    height: 500px;
    .centerSearch {
      display: flex;
      flex-direction: row;
    }
    .table {
      height: calc(500px - 15px);
      overflow: auto;
    }
  }
  .right {
    flex: 1;
    max-width: 50%;
    height: 500px;
  }
}
::v-deep .handle-dialog {
  height: 100%;
  margin-top: 10px;
}
::v-deep .el-table__header-wrapper .el-checkbox {
  display: none;
}
</style>

3、JS代码

<script>
import {
  getHYXMMXWHByIdItem,
  getItemByPinyinWubi
} from '@/api/menZhenAPI/huaYanjiChu/huaYanXMMLMXWH'
export default {
  name: 'HuaYanMNKDDialog',
  props: {
    labWorkOptions: {
      type: Array,
      default: () => []
    },
    value: {
      type: Boolean,
      default: false
    },
    data: {
      type: Object,
      default: () => ({})
    },
    rightTableData: {
      type: Array,
      default: () => []
    }
  },
  data() {
    return {
      currentNodekey: [],
      formData: {},
      yiZhuMLID: '',
      queryString: '',
      leftTableData: [],
      centerTableData: [],
      tableData: [],
      defaultProps: {
        children: 'children',
        label: 'yiZhuMLMC'
      },
      addData: [],
      tableInfo: {},
      rightData: [],
      leftEvents: {
        'row-click': (row) => {
          this.getHuaYanXMById(row)
        }
      },
      centerEvents: {
        select: (selection, row) => {
          console.log('selection', selection)
          console.log('row', row)
          const flag = this.rightData.findIndex((item) => item.huaYanID === row.huaYanID)
          if (flag === -1) {
            if (row.lianDongHao !== null) {
              this.centerTableData.forEach((item) => {
                if (item.lianDongHao === row.lianDongHao) {
                  this.rightData.push({
                    muLuID: item.muLuId,
                    huaYanID: item.huaYanID,
                    huaYanXMMC: item.huaYanXMMC,
                    paiXu: item.paiXu,
                    lianDongHao: item.lianDongHao,
                    zhuCiXiang: null
                  })
                  console.log('item', item)
                  console.log('this.rightData', this.rightData)
                }
              })
            } else {
              this.rightData.push({
                muLuID: row.muLuId,
                huaYanID: row.huaYanID,
                huaYanXMMC: row.huaYanXMMC,
                paiXu: row.paiXu,
                lianDongHao: row.lianDongHao,
                zhuCiXiang: null
              })
              console.log(this.rightData)
            }
          } else {
            if (row.lianDongHao === null) {
              this.rightData.splice(flag, 1)
            } else {
              this.centerTableData.forEach((item) => {
                if (item.lianDongHao === row.lianDongHao) {
                  const index = this.rightData.findIndex((item) => item.huaYanID === row.huaYanID)
                  this.rightData.splice(index, 1)
                }
              })
            }
            this.$refs.multipleTable.getTableRef().clearSelection()
          }
          this.chenckByHuaYanID()
        },
        // 这是主要方法其他地方的函数方法可以尽量不看
        'row-dblclick': (row) => {
          const currentKey = row.yiZhuMLID || row.muLuID
          this.$nextTick(() => {
            // tree节点的id
            // this.currentNodekey = row.yiZhuMLID || row.muLuID
            this.currentNodekey = []
            for (let i = 0; i < this.$refs.tree.store._getAllNodes().length; i++) {
              if (currentKey === this.$refs.tree.store._getAllNodes()[i].data.yiZhuMLID) {
                this.$refs.tree.setCurrentKey(currentKey)
                this.currentNodekey.push(currentKey)
              }
            }
            getHYXMMXWHByIdItem(currentKey).then((res) => {
              if (res.data) {
                console.log(row)
                this.centerTableData = res.data
                this.chenckByHuaYanID()
                // 获取数据后定位
                setTimeout(() => {
                  this.$tools.tableLocateKey(
                    row.huaYanID,
                    'huaYanID',
                    this.centerTableData,
                    this.$refs['multipleTable'].$refs.tableData
                  )
                }, 200)
                // 让高亮元素出现在视图区域
                document
                  .querySelector(
                    '.el-tree--highlight-current .el-tree-node.is-current>.el-tree-node__content'
                  )
                  .scrollIntoView()
              }
            })
          })
        }
      },
      leftColumns: [
        {
          label: '化验项目名称',
          prop: 'mingCheng',
          minWidth: '120px'
        }
      ],
      centerColumns: [
        {
          label: '请选择化验项目',
          prop: 'huaYanXMMC',
          minWidth: '120px'
        }
      ],
      rightColumns: [
        {
          prop: 'huaYanXMMC',
          label: '化验项目名称',
          minWidth: '150px'
        },
        {
          prop: '',
          label: '类别',
          minWidth: '50px'
        },
        {
          prop: '',
          label: '医保类别',
          minWidth: '80px'
        },
        {
          prop: '',
          label: '目录名称',
          minWidth: '80px'
        },
        {
          prop: '',
          label: '状态标志',
          minWidth: '80px'
        },
        {
          prop: '',
          label: '医嘱备注',
          minWidth: '80px'
        },
        {
          prop: '',
          label: '首次录入时间',
          minWidth: '120px'
        },
        {
          prop: '',
          label: '医嘱用户',
          minWidth: '80px'
        }
      ],
      operations: [
        {
          text: '删除',
          type: 'text',
          class: 'el-text-color-del',
          callback: (row) => {
            this.delHandleCancelFormClick(row)
          }
        }
      ]
    }
  },
  computed: {
    visible: {
      get() {
        return this.value
      },
      set(value) {
        this.$emit('update:value', false)
      }
    }
  },
  watch: {
    visible(val) {
      if (val) {
        this.rightData = Object.assign([], this.rightTableData)
        this.queryString = ''
      } else {
        this.centerTableData = []
      }
    }
  },
  created() {},
  methods: {
    onSearch() {
      getItemByPinyinWubi({
        key: this.queryString,
        zhenLiaoLX: this.data.zhenLiaoLX
      }).then((res) => {
        if (res) {
          this.centerTableData = res.data.map((item) => {
            return {
              huaYanID: item['huaYanID'],
              huaYanXMMC: item['huaYanMC'],
              yiZhuMLID: item['yiZhuMLID'],
              yiZhuMLMC: item['yiZhuMLMC']
            }
          })
          this.queryString = ''
        }
      })
    },
  }
}
</script>

4、el-table的封装

<template>
  <div class="table-box">
    <el-table
      ref="tableData"
      v-loading="loading"
      style="width: 100%"
      :row-key="rowKey"
      :data="tableData"
      :height="tableHeight"
      highlight-current-row
      v-bind="tableInfo"
      :span-method="objectSpanMethod"
      v-on="events"
      @selection-change="handleSelectionChange"
    >
      <slot name="expand" />
      <el-table-column v-if="selectAllTemplate" min-width="140" label="全选模板列表">
        <template slot-scope="{ row }">
          <div>
            <el-checkbox
              v-model="row.all"
              @change="muBanAllToggleSelection($event, tableData, row)"
            >
              {{ row.muBanMC }}
            </el-checkbox>
          </div>
        </template>
      </el-table-column>
      <!-- 多选 -->
      <el-table-column
        v-if="needSelect"
        type="selection"
        reserve-selection
        width="55"
        align="center"
      />
      <el-table-column v-if="hasIndex" label="序号" width="50" type="index" />
      <template v-for="(item, index) in tableColumn">
        <!-- 此列需要自定义 -->
        <el-table-column
          v-if="item.isSlot"
          :key="'%' + index"
          :show-overflow-tooltip="showOverflowTooltip"
          v-bind="item"
          :render-header="item.renderHeader"
          v-on="events"
        >
          <template slot-scope="{ row, $index }">
            <ex-slot
              v-if="item.render"
              :render="item.render"
              :row="row"
              :index="$index"
              :column="item"
              :class="item.prop"
              :default-value="item.defaultValue"
            />
            <slot v-else :name="item.prop" :row="row" />
          </template>
        </el-table-column>
        <!-- 正常列 -->
        <el-table-column
          v-else
          :key="'%' + index"
          :show-overflow-tooltip="showOverflowTooltip"
          v-bind="item"
          v-on="events"
        />
      </template>
      <el-table-column v-if="hasOperation" fixed="right" label="操作" :min-width="operationWidth">
        <!-- <template v-if="!btnButton || btnButton.length === 0" slot-scope="scope">
          <slot name="operation" :row="scope.row" :index="scope.$index" />
        </template> -->
        <template v-if="btnButton.length" slot-scope="{ row, column, $index }">
          <el-button
            v-for="(value, i) in btnButton"
            :key="'$' + i"
            size="small"
            :type="value.type"
            :icon="value.icon"
            :class="value.class"
            @click="value.callback(row, column, $index)"
          >
            {{ value.text }}
          </el-button>
        </template>
      </el-table-column>
    </el-table>
    <!-- 分页 -->
    <div
      v-if="isNeedPagination"
      style="display: flex; justify-content: flex-end; align-item: centerl; padding-top: 15px"
    >
      <el-pagination
        ref="pagination"
        :page-sizes="pageSizes"
        :page-size.sync="computedPageSize"
        :hide-on-single-page="isSinglePageHide"
        layout="total, sizes, prev, pager, next, jumper"
        :current-page.sync="computedCurrentPage"
        :total="total"
        :pager-count="pagerCount"
        @current-change="currentChange"
        @size-change="sizeChange"
      />
    </div>
  </div>
</template>
<script>
// 自定义组件的内容
const exSlot = {
  functional: true,
  props: {
    row: Object,
    render: Function,
    index: Number,
    column: {
      type: Object,
      default: null
    },
    defaultValue: [Number, String]
  },

  render: (h, ctx) => {
    const params = {
      row: ctx.props.row,
      index: ctx.props.index
    }
    const defaultValue = ctx.props.defaultValue
    params.column = ctx.props.column || {}
    return h(
      'div',
      {
        class: [
          params.column.prop || '',
          params.column.class || params.column.className || ''
        ].join('')
      },
      [ctx.props.render(h, params) || defaultValue]
    )
  }
}
export default {
  name: 'PublicTable',
  components: {
    'ex-slot': exSlot
  },
  props: {
    // key
    rowKey: {
      type: String,
      default: ''
    },
    // 超出行是否隐藏不换行
    showOverflowTooltip: {
      type: Boolean,
      default: true
    },
    // 是否需要多选
    needSelect: {
      type: Boolean,
      default: false
    },
    // 是否需要序号
    hasIndex: {
      type: Boolean,
      default: false
    },
    // 是否需要分页
    isNeedPagination: {
      type: Boolean,
      default: true
    },
    // 是否单页隐藏,默认为true
    isSinglePageHide: {
      type: Boolean,
      default: false
    },
    // 当前页页码,支持.sync修饰符
    currentPage: {
      type: Number,
      default: 1
    },
    // 页码显示数据量
    pagerCount: {
      type: Number,
      default: 7
    },
    // 每页数据条数, 支持.sync修饰符默认为每页10条
    pageSize: {
      type: Number,
      default: 20
    },
    // 数据总条数
    total: {
      type: Number,
      default: 0
    },
    // 每页多少数据
    pageSizes: {
      type: Array,
      required: false,
      default: () => [20, 40, 80, 100]
    },
    tableInfo: {
      type: Object,
      default: () => {}
    },
    // 获取数据时是否需要加载loading
    loading: {
      type: Boolean,
      default: false
    },
    tableData: {
      type: Array,
      default: () => []
    },
    // 表格展示数据
    tableColumn: {
      type: Array,
      default: () => []
    },
    // 是否需要操作列
    hasOperation: {
      type: Boolean,
      default: true
    },
    // 操作列
    btnButton: {
      type: Array,
      default: () => []
    },
    // 操作列宽度
    operationWidth: {
      type: String,
      default: '120px'
    },
    // 表格方法
    events: {
      type: Object,
      default: () => {}
    },
    templateSelectAll: {
      type: Boolean,
      default: false
    },
    // 合并单元格
    objectSpanMethod: {
      type: Function,
      default: () => {}
    },
    muBanAllToggleSelection: {
      type: Function,
      default: () => {}
    },
    selectAllTemplate: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {}
  },
  computed: {
    computedCurrentPage: {
      get() {
        return this.currentPage
      },
      set(val) {
        this.$emit('update:currentPage', val)
      }
    },
    computedPageSize: {
      get() {
        return this.pageSize
      },
      set(val) {
        this.$emit('update:pageSize', val)
      }
    },
    tableHeight() {
      return !this.isNeedPagination ? '100%' : 'calc(100% - 47px)'
    }
  },
  mounted() {},
  methods: {
    getTableRef() {
      return this.$refs.tableData
    },
    getRefPagination() {
      return this.$refs.pagination
    },
    // 页面切换事件  通过 @currentChange 绑定
    currentChange(val) {
      this.$emit('currentChange', val)
    },
    // 每页条数切换事件,通过@sizeChange 绑定
    sizeChange(val) {
      this.$emit('sizeChange', val)
    },
    handleSelectionChange(val) {
      this.$emit('selectionChange', val)
    }
  }
}
</script>
<style lang="scss" scoped>
.table-box {
  flex: 1;
  overflow: hidden;
  width: 100%;
  height: 100%;
}
</style>

5、el-table定位数据高亮的方法

/**
 * table表格数据定位
 * @param {value} 查询的value唯一值
 * @param {tabKey} tableData数据中的key属性
 * @param {tableData} table表格数据源tableData
 * @param {tableRefs} table表格标签tableRefs
 * @returns
 */
function tableLocateKey(value, tabKey, tableData, tableRefs) {
  let index = tableData.findIndex((i) => {
    return value === i[tabKey]
  })
  let vm = tableRefs.$el
  vm.querySelectorAll('.el-table__body tr')[index].scrollIntoView()
  //让定位到的这条数据产生高亮效果
  tableRefs.setCurrentRow(tableData[index])
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值