实现select的复选、全选、清空、搜寻等性能

<template>  <a-spin :spinning="loading" tip="申请中...">    <div class="workCurve">      <x-card>        <div slot="content" class="table-page-search-wrapper">          <a-form layout="inline">            <span class="search-form-left" style="width:100%">              <a-row :gutter="0">                <a-col :md="4" :sm="24">                  <a-form-item label="">                    <a-radio-group v-model="type" style="width:230px" @change="typeChange">                      <a-radio value="0">                        投产日期                      </a-radio>                      <a-radio value="1">                        措施日期                      </a-radio>                    </a-radio-group>                  </a-form-item>                </a-col>                <a-col :md="4" :sm="12" style="margin-left:20px">                  <a-form-item label="拉齐数据">                    <a-select                      :maxTagCount="1"                      mode="multiple"                      style="width: 100%;min-width:240px"                      placeholder="请抉择拉齐数据"                      v-model="lqData"                    >                      <a-select-option v-for="(item, index) in lqOptions" :key="index" :value="item.value">{{                        item.name                      }}</a-select-option>                    </a-select>                  </a-form-item>                </a-col>                <a-col :md="4" :sm="24">                  <a-form-item label="向前拉齐点数">                    <a-input-number                      :disabled="type === '0'"                      v-model="beforeCount"                      :precision="0"                      style="width: 100%;"                    />                  </a-form-item>                </a-col>                <a-col :md="4" :sm="24">                  <a-form-item label="向前每段天数">                    <a-input-number :disabled="type === '0'" v-model="spanLenth" :precision="0" style="width: 100%;" />                  </a-form-item>                </a-col>                <a-col :md="4" :sm="24">                  <a-form-item label="向后拉齐点数">                    <a-input-number v-model="afterCount" :precision="0" style="width: 100%;" />                  </a-form-item>                </a-col>                <a-col :md="4" :sm="24">                  <a-form-item label="向后每段天数">                    <a-input-number v-model="afterDaily" :precision="0" style="width: 100%;" />                  </a-form-item>                </a-col>                <a-col :md="4" :sm="24">                  <a-form-item>                    <a-button type="primary" @click="handleQuery"                      ><img style="width:12px;margin-right:4px" src="@/assets/search-icon.png" alt="" />查问</a-button                    >                  </a-form-item>                </a-col>                <span class="table-page-search-submitButtons button-group-right">                  <a-button type="primary" @click="visible = true">查看数据表</a-button>                </span>              </a-row>            </span>          </a-form>        </div>      </x-card>      <div>        <a-row :gutter="[5, 5]" type="flex">          <a-col :span="4" flex="240px">            <QkTree              ref="qkTree"              :type="'well'"              :disabledJh="type === '0' ? true : false"              :multiple="false"              :treeStyle="'height:calc(100vh - 227px)'"              :checkable="false"              @selectedNode="selectedNodeHandle"            ></QkTree>          </a-col>          <a-col :span="15" flex="calc(100% - 240px - 340px - 10px)" style="width:calc(100% - 240px - 340px - 10px)">            <a-card class="charts-contaniner">              <div class="charts-box">                <curve-chart ref="curveChart"></curve-chart>              </div>            </a-card>          </a-col>          <a-col :span="5" flex="340px">            <a-card class="charts-contaniner">              <div style="height: calc(100vh - 395px);overflow: auto;">                <a-tree-select                  v-if="false"                  v-model="rightJh"                  :maxTagCount="1"                  @change="rightJhChange"                  :dropdownStyle="{ maxHeight: '300px', overflow: 'auto' }"                  style="width:100%;margin-bottom:10px"                  :tree-data="rightTreeData"                  tree-checkable                  allowClear                  :treeDefaultExpandAll="true"                  :replaceFields="{ children: 'children', title: 'jh', key: 'jh', value: 'jh' }"                  placeholder="请输出井号前缀并抉择"                >                </a-tree-select>                <a-select                  style="width:100%;margin-bottom:10px"                  class="select"                  mode="multiple"                  v-model="rightJh"                  :maxTagCount="1"                  placeholder="请输出井号前缀并抉择"                  @change="rightJhChange"                >                  <div slot="dropdownRender" slot-scope="menu">                    <div style="padding:4px; cursor: pointer;" @mousedown="e => e.preventDefault()">                      <!-- 全选、重置 -->                      {{ checkAllLoading }}                      <a-button                        class="btn"                        type="primary"                        style="margin-right:10px"                        @click="checkAllField"                        :loading="checkAllLoading"                      >                        全选                      </a-button>                      <a-button class="btn" @click="resetRightJh">重置</a-button>                    </div>                    <a-divider style="margin: 4px 0;" />                    <VNodes :vnodes="menu" />                  </div>                  <a-select-option v-for="item in dataImport" :key="item.jh" :value="item.jh">                    {{ item.jh }}                  </a-select-option>                </a-select>                <!-- :show-checked-strategy="SHOW_PARENT" -->                <a-table                  :loading="loadingImport"                  :scroll="{ y: 'calc(100vh - 495px)' }"                  :rowSelection="{                    selectedRowKeys: selectedRowKeys,                    onChange: onSelectChange,                    fixed: true,                    columnWidth: 50                  }"                  :columns="columnsImport"                  :data-source="rightTableData"                  bordered                  size="small"                  :pagination="false"                  :rowKey="(record, index) => record.jh"                >                  <span slot="rqStr" slot-scope="text, record">                    <a-input                      :placeholder="''"                      @change="e => handleChange(e, record.rqStr, 'rqStr')"                      v-model="record.rqStr"                    >                    </a-input>                  </span>                </a-table>              </div>              <div style="width: 100%;text-align: center;">                <a-button style="margin-top: 15px;" type="primary" @click="handleDownload">模板下载</a-button><br />                <a-upload                  name="file"                  :before-upload="beforeUpload"                  :customRequest="handleUpload"                  accept=".xls,.xlsx"                  :showUploadList="false"                >                  <a-button type="primary" style="margin-top: 15px;"> <a-icon type="import" />导入 </a-button>                </a-upload>                <br />                <a-button style="margin-top: 15px;" type="primary" @click="handleClear">清空</a-button>              </div>            </a-card>          </a-col>        </a-row>      </div>      <a-modal        :footer="null"        v-model="visible"        :width="1200"        title="拉齐比照数据"        :destroyOnClose="true"        @cancel="cancelTableData"        @ok="setTableData"      >        <a-table :columns="columns" size="small" :data-source="data" bordered>          <div v-for="col in columns.map(it => it.dataIndex)" :key="col" :slot="col" slot-scope="text, record">            <div>              <a-input-number                :min="-999999"                :max="999999"                v-if="record.editable"                style="margin: -5px 0;width:100%"                :value="text"                @change="e => handleChange(e, record.key, col)"              />              <template v-else>                {{ text }}              </template>            </div>          </div>          <template slot="operation" slot-scope="text, record">            <div class="editable-row-operations">              <span v-if="record.editable">                <a @click="() => save(record.key)">保留</a>                <a @click="() => cancel(record.key)" style="margin-left:15px">勾销</a>              </span>              <span v-else>                <a :disabled="editingKey !== ''" @click="() => edit(record.key)">编辑</a>              </span>            </div>          </template>        </a-table>      </a-modal>    </div>  </a-spin></template><script>import { XCard } from '@/components'import { handleXlsRes } from '@/utils/exportXls.js'import CurveChart from '../components/CurveChart.vue'import QkTree from '@/components/QkTree/index.vue'import _ from 'lodash'import {  curveApi,  importApi,  getTcrqJhListApi,  getImportTemplateApi} from '@/api/modular/main/prodIndicator/compair.js'export default {  components: {    XCard,    QkTree,    CurveChart,    VNodes: {      functional: true,      render: (h, ctx) => ctx.props.vnodes    }  },  data() {    return {      checkAllLoading: false,      selectedRowKeys: [],      selectedRows: [],      lqOptions: [        // 总井数、开井数、日产液量、日产油量、含水、动液面、阶段累计产液、阶段累计产油        { name: '总井数', value: 'zjs' },        { name: '开井数', value: 'kjs' },        { name: '日产液量', value: 'rcyel' },        { name: '日产油量', value: 'rcyl' },        { name: '含水', value: 'hsb' },        { name: '动液面', value: 'dym' },        { name: '阶段累计产液', value: 'ljcyel' },        { name: '阶段累计产油', value: 'ljcyl' }      ],      lqData: ['zjs', 'kjs', 'rcyel', 'rcyl', 'hsb', 'dym', 'ljcyel', 'ljcyl'],      loading: false,      mode: ['month', 'month'],      month: [],      queryParam: {},      columns: [        {          title: '阶段号',          dataIndex: 'stage',          scopedSlots: { customRender: 'stage' }        },        {          title: '总井数',          dataIndex: 'zjs',          scopedSlots: { customRender: 'zjs' }        },        {          title: '开井数',          dataIndex: 'kjs',          scopedSlots: { customRender: 'kjs' }        },        {          title: '日产液量',          dataIndex: 'rcyel',          scopedSlots: { customRender: 'rcyel' }        },        {          title: '日产油量',          dataIndex: 'rcyl',          scopedSlots: { customRender: 'rcyl' }        },        {          title: '动液面(m)',          dataIndex: 'dym',          scopedSlots: { customRender: 'dym' }        },        {          title: '含水(%)',          dataIndex: 'hsb',          scopedSlots: { customRender: 'hsb' }        },        {          title: '阶段累计产液',          dataIndex: 'ljcyel',          scopedSlots: { customRender: 'ljcyel' }        },        {          title: '阶段累计产油',          dataIndex: 'ljcyl',          scopedSlots: { customRender: 'ljcyl' }        }      ],      wellOptions: [],      visible: false,      editingKey: '',      data: [],      cacheData: [],      renderData: {        xdata: [],        data: []      },      chartsYName: [        '总井\n数(口)',        '开井\n数(口)',        '日产\n液(t)',        '日产\n油(t)',        '含水\n(%)',        '动液\n面(m)',        '阶段累计产液',        '阶段累计产油'      ], //'开井\n数(口)',      chartsName: [        {          name: '总井数',          index: 0,          color: '#4b5cc4',          type: 'line',          key: 'zjs'        },        {          name: '开井数',          index: 1,          color: '#0c8918',          type: 'line',          key: 'kjs'        },        {          name: '日产液',          index: 2,          color: '#ff2aff',          type: 'line',          key: 'rcyel'        },        {          name: '日产油',          index: 3,          color: 'red',          type: 'line',          key: 'rcyl'        },        {          name: '含水',          index: 4,          color: '#6fff6f',          type: 'line',          key: 'hsb'        },        {          name: '动液面',          index: 5,          color: '#ffe16b',          type: 'line',          key: 'dym'        },        {          name: '阶段累计产液',          index: 6,          color: '#f05654',          type: 'line',          key: 'ljcyel'        },        {          name: '阶段累计产油',          index: 7,          color: '#c9dd22',          type: 'line',          key: 'ljcyl'        }      ],      miningStatusData: {},      devHistory: '',      maxmonth: 100,      tabPosition: 'jzzjg',      sliderValue: [0, 0],      btnLabel: '锁定距离',      isLock: false,      intervalDate: 0,      monthDate: [],      columnsImport: [        {          title: '井号',          dataIndex: 'jh',          align: 'center'        },        {          title: '日期',          dataIndex: 'rqStr',          align: 'center',          width: 140,          scopedSlots: { customRender: 'rqStr' }        }      ],      tcJhList: [],      rightJh: [],      rightTableData: [],      dataImport: [],      spanLenth: 1,      beforeCount: 1,      afterCount: 1,      afterDaily: 1,      type: '0',      loadingImport: false,      selectedQk: {},      selectedCw: {}    }  },  computed: {    jhList() {      if (this.selectedQk.title && this.selectedQk.qkdm) {        if (this.type === '1') {          this.loadingImport = true          //措施日期,jh取值为左侧树;投产日期,井号list数据为接口返回          let jhArr = _.map(this.selectedQk.children, 'jh')          let tableData = []          jhArr.filter(item => {            if (!!item) {              tableData.push({ jh: item })            }            return !!item          })          this.loadingImport = false          return tableData        }      } else {        if (this.type === '1') {          this.$message.warning('请抉择区块')        }      }      return []    },    queryData() {      return {        beforeCount: this.beforeCount,        beforeDaily: this.beforeDaily,        afterCount: this.afterCount,        afterDaily: this.afterDaily,        wellList: this.selectedRows      }    },    selectedQkInfo() {      let arr = [this.selectedQk]      return {        zyqdm: arr && arr[0] ? arr[0].zyqdm : null,        qkdm: arr && arr[0] ? arr[0].qkdm : null,        cyddm: arr && arr[0] ? arr[0].cyddm : null      }    },    rightTreeData() {      let arr = []      if (this.dataImport?.length) {        arr = [{ jh: '全选', children: this.dataImport }]      }      return arr    }  },  methods: {    resetRightJh() {      this.rightJh = []      this.rightJhChange(this.rightJh)    },    checkAllField() {      this.checkAllLoading = true      let jhArr = []      this.dataImport.forEach(item => {        jhArr.push(item.jh)      })      this.rightJh = jhArr      this.rightJhChange(this.rightJh)    },    rightJhChange(val) {      console.log(this.checkAllLoading)      // console.log(22, val)      let arr = []      let arr2 = []      this.dataImport.forEach(iitem => {        let obj = val.find(valItem => {          return iitem.jh === valItem        })        if (!obj) {          arr.push(iitem)        } else {          arr2.push(iitem)        }      })      this.rightTableData = arr2.concat([])      this.defaultCheckedAll(arr2) //选中以后下拉井号      if (this.checkAllLoading) {        // setTimeout(() => {        //   this.checkAllLoading = false        // }, 1000)      }    },    filterOption(input, option) {      return option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0    },    typeChange(val) {      this.dataImport = []      // 类型变更,表格选中项重置      this.selectedRowKeys = []      this.selectedRows = []      if (this.type === '0') {        this.beforeCount = null        this.beforeDaily = null        this.getTcJhList() //切换时,从新申请      } else {        this.beforeCount = 1        this.beforeDaily = 1        this.dataImport = this.jhList        this.rightTableData = []        this.defaultCheckedAll([])      }      // 重置选中数据      this.rightTableData = []      this.defaultCheckedAll([])      // 重置曲线      this.setCurveData([])      this.data = []    },    onSelectChange(selectedRowKeys, selectedRows) {      this.selectedRowKeys = selectedRowKeys      this.selectedRows = selectedRows      this.rightJh = this.selectedRowKeys //表格抉择内容变更同步批改a-tree-select项    },    getTcJhList() {      if (!this.selectedQk.title) {        this.tcJhList = []        this.dataImport = []        this.defaultCheckedAll([])        return      }      // 获取投产日期下所有井号      let params = Object.assign({}, this.queryData, this.selectedQkInfo)      // 点击 作业区 和采油队时 提醒用户点击 请抉择区块。      if (!params.qkdm) {        this.$message.warning('请抉择区块')        return      }      this.loadingImport = true      getTcrqJhListApi(params)        .then(res => {          this.loadingImport = false          if (res.data) {            this.tcJhList = res.data            this.rightJh = []            this.dataImport = this.tcJhList            this.rightTableData = []            this.defaultCheckedAll([])          } else {            this.$message.warning(res.message)          }        })        .catch(() => {          this.loadingImport = false        })    },    defaultCheckedAll(arr) {      let indArr = []      arr.forEach(item => {        indArr.push(item.jh)      })      // 默认选中全副      this.onSelectChange(indArr, arr)    },    selectedNodeHandle(value) {      this.selectedQk = value      if (this.type === '0') {        this.getTcJhList()      } else {        this.dataImport = this.jhList        this.rightTableData = []        this.defaultCheckedAll([])      }    },    // 用表格编辑后的数据从新绘制曲线    setTableData() {      this.visible = false      this.setCurveData(this.data)    },    cancelTableData() {      this.visible = false      this.cancel(this.editingKey)    },    handleChange(value, key, column) {      const newData = [...this.dataImport]      const target = newData.find(item => key === item.key)      if (target) {        target[column] = value        this.dataImport = newData      }    },    edit(key) {      const newData = [...this.data]      const target = newData.find(item => key === item.key)      this.editingKey = key      if (target) {        target.editable = true        this.data = newData      }    },    save(key) {      const newData = [...this.data]      const newCacheData = [...this.cacheData]      const target = newData.find(item => key === item.key)      const targetCache = newCacheData.find(item => key === item.key)      if (target && targetCache) {        delete target.editable        this.data = newData        Object.assign(targetCache, target)        this.cacheData = newCacheData      }      this.editingKey = ''    },    cancel(key) {      const newData = [...this.data]      const target = newData.find(item => key === item.key)      this.editingKey = ''      if (target) {        Object.assign(          target,          this.cacheData.find(item => key === item.key)        )        delete target.editable        this.data = newData      }    },    getCurveData() {      let params = Object.assign({}, this.queryData, {})      if (this.type === '0') {        params.beforeCount = null        params.beforeDaily = null        //  向前拉齐点数:禁用,并且不传参置为null        // 向前拉齐每段天数:禁用,并且不传参置为null      }      let _this = this      _this.loading = true      curveApi(params)        .then(res => {          if (res.code != 200) {            this.$message.warning(res.message)            _this.setCurveData([])            _this.data = []            return          }          if (res.success && res.data.length > 0) {            _this.data = res.data            for (var m = 0; m < _this.data.length; m++) {              _this.data[m]['key'] = m.toString()            }            _this.cacheData = _this.data.map(item => ({ ...item }))            _this.miningStatusData = res.data[0]            _this.setCurveData(res.data)          } else {            _this.setCurveData([])            _this.data = []          }          _this.loading = false        })        .finally(err => {          _this.loading = false        })    },    setCurveData(data) {      let chartsNameData = []      this.renderData = {        xdata: [],        data: [],        chartsYName: []      }      let showCurveData = this.lqData      let chartsNameShow = []      let chartsYNameShow = []      showCurveData.forEach((currentItem, index) => {        let obj = this.chartsName.find(item => {          return item.key === currentItem        })        if (obj) {          obj.index = index          let name = obj.name.length > 3 ? obj.name.slice(0, 3) + '\n' + obj.name.slice(3) : obj.name          chartsYNameShow.push(name)          chartsNameShow.push(obj)        }      })      chartsNameData = chartsNameShow      this.renderData.chartsYName = chartsYNameShow || this.chartsYName      for (var i = 0; i < data.length; i++) {        this.renderData.xdata.push('阶段' + data[i].stage)      }      for (var n = 0; n < chartsNameData.length; n++) {        let obj = {          name: chartsNameData[n].name,          index: chartsNameData[n].index,          color: chartsNameData[n].color,          type: chartsNameData[n].type,          data: []        }        for (var i = 0; i < data.length; i++) {          let key = chartsNameData[n].key          obj.data.push(data[i][key] ? data[i][key] - 0 : 0)        }        this.renderData.data.push(obj)      }      this.$refs.curveChart.setData(this.renderData)    },    handleQuery() {      if (!this.afterCount) {        return this.$message.warning('请输出向后拉齐点数')      }      if (!this.afterDaily) {        return this.$message.warning('请输出向后每段天数')      }      if (!this.selectedRows.length) {        return this.$message.warning('井号不能为空')      }      let flag = true      if (this.selectedRows) {        this.selectedRows.forEach(item => {          if (!item.rqStr) {            flag = false          }        })      }      if (!flag) {        this.$message.warning('所选井号日期不能为空')        return      }      this.getCurveData()    },    // 模板下载    handleDownload() {      getImportTemplateApi().then(res => {        // handleXlsRes(res)        const dataJson = res.data        const aLink = document.createElement('a')        const blob = new Blob([dataJson], { type: 'application/force-download; charset=UTF-8' })        aLink.href = URL.createObjectURL(blob)        aLink.setAttribute('download', '拉齐比照模板.xls') // 设置下载文件名称        aLink.click()      })    },    // 导入    beforeUpload(file) {      const extension = file.name.substring(file.name.lastIndexOf('.') + 1)      if (extension !== 'xlsx' && extension !== 'xls') {        this.$message.error('只能上传excel文件')        return false      }      const isLt10M = file.size / 1024 / 1024 < 10      if (!isLt10M) {        this.$message.error('大小不能超过10MB!')        return false      }      return extension && isLt10M    },    handleUpload(file) {      const _this = this      const formData = new FormData()      formData.append('file', file.file)      importApi(formData)        .then(response => {          if (Object.prototype.toString.call(response.data) === '[object Blob]') {            // 先判断是不是blob格局            if (response.data.type.includes('application/json')) {              // 判断是不是非凡状况(json)              const reader = new FileReader()              reader.onload = function() {                const res = reader.result                const result = JSON.parse(res) // blob格局转成json                if (result.code === 200) {                  // 导出超出限度                  _this.$message.success('导入胜利')                  _this.dataImport = result.data                  _this.rightTableData = []                  _this.defaultCheckedAll([])                } else {                  _this.$message.error(result.message)                }              }              reader.readAsText(response.data)            } else {              // 导入格局谬误              handleXlsRes(response)            }          }        })        .catch(e => {          // 接管异样 并提醒          _this.$message.error(e.message)        })    },    handleClear() {      this.dataImport = []      this.rightTableData = []      this.defaultCheckedAll([])    }  },  created() {}}</script><style lang="less" scoped>.charts-contaniner {  overflow: auto;  ul,  li {    margin: 0;    padding: 0;    list-style-type: none;  }  .charts-box {    width: 100%;    height: calc(100vh - 253px);    overflow: hidden;  }}.cardContent {  min-height: 200px;  p {    margin-bottom: 6px;    color: #1890ff;  }}.workCurve {  /deep/ .ant-card-body {    padding: 12px;  }  /deep/ .ant-form-item {    margin-bottom: 6px;  }  /deep/ .ant-modal-body {    padding: 12px;  }}.btnBoxRight {  padding-top: 12px;  text-align: right;  button {    margin: 0;  }}.bottomTabs {  background-color: #fff;  padding-top: 8px;  /deep/ .ant-radio-button-wrapper {    width: 50%;    text-align: center;  }}/deep/.ant-table-small > .ant-table-content > .ant-table-body {  margin: 0 !important;}</style>