如何实现下拉框里面嵌套表格

292 阅读1分钟

下拉表格框代码实现

如何实现下拉框里面嵌套表格

image.png

<template>
  <div class="TableSelect" :style="styles" v-clickoutside="handleOnBlur" ref="inputRef">
    <Input
      v-model="searchLabel"
      :placeholder="placeholder"
      :size="size"
      :disabled="disabled"
      clearable
      @on-change="searchQueryChange"
      @on-clear="handleQueryClear"
      @on-blur="handleBlurInput"
    />
    <transition name="fade">
      <div :class="inGoodsDelivery ? 'search-content-goods-delivery' : 'search-content'" transfer>
        <Table
          :style="positionTop"
          transfer
          size="large"
          max-height="250"
          v-show="isTableShow && searchLabel"
          border
          :columns="tableColumn"
          :data="tableData"
          @on-row-click="handelRowClick"
          :loading="loading"
        >
          <template slot="goodsName" slot-scope="{ row }">
            <Poptip trigger="hover" :content="row.goodsName">
              <div class="goods-name-col-content">{{row.goodsName}}</div>
            </Poptip>
          </template>
        </Table>
      </div>
    </transition>
  </div>
</template>

![image.png](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/7850b471c6704994bf1a8229ec150a5b~tplv-k3u1fbpfcp-watermark.image?)
<script>
import clickoutside from '~/utils/clickoutside'
import { tableColumn, tableColumnBatch,tableColumnMin } from './columns'

export default {
  name: 'TableSelect',
  directives: {
    clickoutside
  },
  props: {
    apiType: {
      type: String,
      default: '',
    },
    value: {
      type: String
    },

    disabled:{
      type: Boolean
    },

    placeholder: {
      type: String
    },

    searchType: {
      type: String,
      default: 'goodsCode'
    },

    size: {
      type: String,
      default: 'default'
    },

    searchStatus: {
      type: String,
      default: ''
    },

    styles: {
      type: String,
      default: 'width:auto;'
    },

    disabled: {
      type: Boolean,
      default: false
    },

    itemIndex: {
      type: Number,
      default: null
    },

    // 筛选框只展示‘货品代码’和‘货品名称’
    onlyShowName: {
      type: Boolean,
      default: false
    },

    // 改变定位
    position: {
      type: Boolean,
      default: false
    },

    // 货品出库统计 - 排除组合货品
    excludeGroup: {
      type: String,
      default: ''
    },
  },

  data() {
    return {
      inGoodsDelivery: false,
      searchLabel: '',
      isTableShow: false,
      tableData: [],
      tableColumn,
      loading: false,
      searchQueryChange: this.$ondebounce(this.handleQueryChange, 800),
      positionTop: {}
    }
  },

  watch: {
    value(val) {
      this.searchLabel = val
    },

    searchLabel(newVal) {
      this.$emit('input', newVal)
    }
  },

  mounted() {
    // 判断路由是在‘货品出库统计’时,加高input框层级
    this.inGoodsDelivery = Boolean(this.$route.name === 'data-statistics/goods-delivery')
    this.searchLabel = this.value
    if(this.onlyShowName) {
      this.tableColumn = tableColumn.filter(item => {
        return item.title === '货品代码' || item.title === '货品名称'
      })
    }
    if (this.apiType === 'stockBatchList') {
      this.tableColumn = this.apiType === 'stockBatchList' ? tableColumnBatch : tableColumn
    }
    if (this.apiType === 'warehouseing') {
      this.tableColumn = tableColumnMin
    }
    
  },

  methods: {
    settingInputVal(val = '') {
      this.searchLabel = val
    },

    // 输入框聚焦
    handleOnFocus() {
      this.isTableShow = true
    },
    handleOnBlur() {
      this.isTableShow = false
    },

    // 点击对应行
    handelRowClick(row, index) {
      this.$emit('on-change', { row, index })
      this.searchLabel = row[this.searchType]
      this.handleOnBlur()
      this.$emit('getid', row.id) // 返回一个id
    },
    handleQueryClear() {
      this.$emit('on-query-clear', this.value)
    },

    // 输入框失焦时
    handleBlurInput() {
      this.$emit('on-blur-input', this.searchLabel, this.searchType, this.itemIndex)
    },

    handleQueryChange (e, type = this.searchType) {
      console.log(e, type);
      // 固定定位的时候改变弹出表格的位置
      let top = (this.$refs.inputRef?.getBoundingClientRect().top) + 40 + 'px'
      this.positionTop = this.position ?  {top} : {}
      
      this.isTableShow = true
      this.loading = true
      let postData = {}
      postData[`${type}`] = e.target.value
      postData.goodsStatus = this.searchStatus
      postData.excludeGroup = this.excludeGroup
      if (this.apiType === 'stockBatchList') {
        for (const [key, value] of Object.entries(postData)) value === '' && (postData[key] = undefined)
        postData.pageIndex = 1
        postData.pageSize = 1000
        this.$API
          .stockBatchList(postData)
          .then((res) => {
            if (res.code === 0) {
              this.tableData = res.data.list
            }
          })
          .finally(() => {
            this.loading = false
          })
      } else {
        this.$API
          .getGoodsInquiry(postData)
          .then((res) => {
            if (res.code === 0) {
              this.tableData = res.data.map((item) => {
                item.goodsQuantity = item.quantity ? item.quantity : 1
                return item
              })
            }
          })
          .finally(() => {
            this.loading = false
          })
      }
    },
  },
}
</script>

<style scoped>
.fade-enter-active,
.fade-leave-active {
  transition: opacity 0.5s;
}

.fade-enter,
.fade-leave-to {
  opacity: 0;
}

.TableSelect {
  position: relative;
}

.search-content {
  position: absolute;
  overflow: auto;
  padding: 8px 2px 28px 2px;
  box-sizing: border-box;
  width: auto;
  z-index: 2;
  margin: 0 0 20px 0;
}
.search-content-goods-delivery {
  position: fixed;
  overflow: auto;
  padding: 8px 2px 28px 2px;
  box-sizing: border-box;
  width: auto;
  z-index: 21;
  margin: 0 0 20px 0;
}
.goods-name-col-content{
  /* border: 1px solid black; */
  width: 170px;
  
  line-height: normal;
  overflow: hidden;
  text-overflow: ellipsis;

}
</style>