vue+elment+table动态表头render-header:多列渲染pop后点击显示只显示当前的pop

问题是这样的:在表头渲染一个按钮,点击会弹出当前列的搜索框pop,当点击第二列弹出pop时其余已经弹出的也不会消失。

就算绑定了点击此处以外消失的指令也没用:

那么怎么解决呢,通过实现发现,双击的时候是可以的,也就是@dblclick  但是通过点击改成了双击后出现搜索层肯定不理想,还是想通过单机点出pop然后再点击其它列的搜索旧的pop消失掉
这时候顺着事件触发思路既然能改事件触发那就改成
@mousedown即可
<div slot="reference" style="margin-left:5px;margin-top: 2px;" @mousedown.stop ="popClick" v-click-outside="closeOver">

 

代码:
父组件表单组件:
<!-- 服务店收货单管理 -->
<template>
  <div class="main">
    <el-card class="box-card">
      <div class="clearfix">
        <span class="card-title">服务店收货单管理</span>
      </div>
      <div class="text item">
        <el-table :data="tableData" @row-click="clickData" style="width: 100%">
          <el-table-column prop="name" label="作业订单" :render-header="renderSpecNameHeader"></el-table-column>
          <el-table-column prop="name" label="收货单号" :render-header="renderSpecNameHeader"></el-table-column>
          <el-table-column prop="name" label="订单日期" :render-header="renderSpecNameHeader"></el-table-column>
          <el-table-column prop="name" label="装箱日期" :render-header="renderSpecNameHeader"></el-table-column>
          <el-table-column prop="name" label="发货时间" :render-header="renderSpecNameHeader"></el-table-column>
          <el-table-column prop="name" label="出货历时" :render-header="renderSpecNameHeader"></el-table-column>
          <el-table-column prop="name" label="妥投时间" :render-header="renderSpecNameHeader"></el-table-column>
          <el-table-column prop="name" label="物流耗时" :render-header="renderSpecNameHeader"></el-table-column>
          <el-table-column prop="name" label="物流状态" :render-header="renderSpecNameHeader"></el-table-column>
          <el-table-column prop="name" label="需求量" :render-header="renderSpecNameHeader"></el-table-column>
          <el-table-column prop="name" label="未发行数" :render-header="renderSpecNameHeader"></el-table-column>
        </el-table>
      </div>
      <div class="task-page">
        <el-pagination
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
          :current-page="pageindex"
          :page-sizes="[10, 20, 30, 40]"
          :page-size="pagesize"
          layout="total, sizes, prev, pager, next, jumper"
          :total="total"
        >
        </el-pagination>
      </div>
    </el-card>
  </div>
</template>

<script>
import TableSelect from './tableSelect.vue'

export default {
  components: {
    TableSelect
  },
  data() {
    return {
      tableData: [{name: '11'}, {name: '22'}],
      tableDataCopy: [{name: '11'}, {name: '22'}],
      filters: [],
      pagesize: 10,
      pageindex: 1,
      total: 0,
    }
  },
  methods: {
    /** 表头搜索 */
    // 渲染**的tableheader
    renderSpecNameHeader (createElement, { column, $index }) {
      const self = this
      // 该列的绑定数据
      // console.log(column.label);
      // 列号
      // console.log($index);
      return createElement(
        'div',
        {
          style: 'display:inline-flex;'
        },
        [
          createElement('div', {
            domProps: {
              innerHTML: column.label
            }
          }),
          createElement(TableSelect, {
            style: 'cursor: pointer;',
            // 组件 prop
            props: {
              type: column.property,
              options: self.specIdOptions, // 下拉框选项
              defaultValue: self.examinerFieldChname, // 默认值
              defaultProps: {
                value: 'examinerFieldName',
                label: 'examinerFieldChname'
              }
            },
            // 事件监听器在 `on` 属性内,
            // 但不再支持如 `v-on:keyup.enter` 这样的修饰器。
            // 需要在处理函数中手动检查 keyCode。
            on: {
              selectChange: self.selectChange,
              resetChange: self.resetChange
              // click: this.clickHandler
            },
            // 仅用于组件,用于监听原生事件,而不是组件内部使用
            // `vm.$emit` 触发的事件。
            nativeOn: {
              // click: this.nativeClickHandler
            }
          })
        ]
      )
    },
    // 搜索回调
    selectChange (data) {
      console.log('搜索回调', data)
      // 自定义筛选框返回数据进行过滤添加到tableData数组中
      const type = data['type']
      const value = data['value']
      this.filters[type] = value
      if (value !== '' && type !== '') {
        this.tableData = this.tableData.filter(
          item => item[type].toString().toLowerCase().includes(value.toString().toLowerCase())
        )
      }
    },
    // 重置回调
    resetChange (data) {
      console.log('重置回调', data)
      delete this.filters[data['type']]
      var tmpData = this.tableDataCopy
      for (const key in this.filters) {
        tmpData = tmpData.filter(
          item => item[key].toString().toLowerCase().includes(this.filters[key].toString().toLowerCase())
        )
      }
      this.tableData = tmpData
    },
    
    clickData() {
      this.$router.push({ name:'orderDetail'})
    },
    // 分页
    handleSizeChange() {},
    handleCurrentChange() {},
  }
}
</script>

<style lang="less" scoped>
.main {
  .clearfix {
    margin-bottom: 20px;
    .card-title {
      font-size: 18px;
      font-weight: 500;
      color: #1E1F23;
    }
  }
  .task-page {
    padding: 0px @pd-16;
    text-align: right;
    padding-top: 16px;
    height: 48px;
  }
}
</style>

子组件:pop和出发点组件

<!-- 表头搜索组件 -->
<template>
  <el-popover placement="bottom" width="200" trigger="manual" v-model="visible" @show="showPopover">
    <el-input
      placeholder="请输入内容"
      v-model="value"
      clearable
      @keyup.enter.native="confirm"
      ref="sInput"
    >
    </el-input>
    <el-button type="primary" size="mini" @click="confirm" style="margin-top:5px;">搜索</el-button>
    <el-button size="mini" @click="resetData">重置</el-button>
    <div slot="reference" style="margin-left:5px;margin-top: 2px;" @mousedown.stop ="popClick" v-click-outside="closeOver">
    <!-- <div slot="reference" style="margin-left:5px;margin-top: 2px;" @dblclick.stop ="popClick" v-click-outside="closeOver"> -->
      <img src="../../../assets/songxia/icon-search.png" style="width: 12px;">
    </div>
  </el-popover>
</template>
<script>
export default {
  data () {
    return {
      value: '',
      visible: false,
      iconColor: false
    }
  },
  props: {
    tableType: {
      type: String,
      default: ''
    },
    type: {
      type: String,
      default: ''
    },
    defaultValue: {
      type: String,
      default: ''
    },
    options: {
      type: Array,
      default: function () {
        return []
      }
    },
    defaultProps: {
      type: Object,
      default: function () {
        return {
          label: 'label',
          value: 'value'
        }
      }
    }
  },
  watch: {
    defaultValue (newVal, oldVal) {
      const self = this
      self.value = newVal
    }
  },
  methods: {
    showPopover () {
      this.$nextTick(() => {
      this.$refs.sInput.focus()
      })
    },
    resetData () {
      console.log('reset')
      this.value = ''
      this.visible = false
      this.iconColor = false
      const self = this
      self.$emit('resetChange', { type: self.type, value: self.value, tableType: self.tableType })
    },
    closeOver () {

      this.visible = false
    },
    popClick (e) {
      e.stopPropagation()
      console.log(e)
      this.visible = !this.visible
    },
    confirm () {
      this.visible = false
      this.iconColor = true
      const self = this
      if (self.value) {
        self.$emit('selectChange', { type: self.type, value: self.value, tableType: self.tableType })
      }
    }
  },
  directives: {
    clickOutside: {
      bind (el, binding, vnode) {
        function clickHandler (e) {
          // 这里判断点击的元素是否是本身,是本身,则返回
          if (el.contains(e.target)) {
            return false
          }
          // 判断指令中是否绑定了函数
          if (binding.expression) {
            // 如果绑定了函数 则调用那个函数,此处binding.value就是handleClose方法
            binding.value(e)
          }
        }
        // 给当前元素绑定个私有变量,方便在unbind中可以解除事件监听
        el.__vueClickOutside__ = clickHandler
        document.addEventListener('click', clickHandler)
      },
      update () {},
      unbind (el, binding) {
        // 解除事件监听
        document.removeEventListener('click', el.__vueClickOutside__)
        delete el.__vueClickOutside__
      }
    }
  }
}
</script>

这样就行了,但是需要注意的是,如果此表单加入了排序 sortable 也是失效的。这时候最好自己指定排序的图标,因为element排序是默认绑定在整个header内的也就是触发header任何dom都会先执行排序干扰显示和隐藏pop的执行。

posted @ 2022-05-06 15:00  少哨兵  阅读(1894)  评论(0编辑  收藏  举报