封装cascader

 <cutCascader :columnList="caliberList"
                           :row="scope.row"
                           :show-all-levels="true"
                           :showLabel="true"
                           :name="'caliberId'"
                           :index="scope.$index"
                           :props="{ checkStrictly: true,children:'children', label: 'name', value: 'id',emitPath:false ,expandTrigger: 'click'}"
                           @change="setCaliberId"></cutCascader>

因为点击下拉框之后失焦blur和change两个事件没有明显先后逻辑。一般来说都使blur会比change前面导致一些问题,还有开启查询filterable之后,搜出来的列表点击之后会先失焦,之后会注销组件不会触发change事件导致很多问题,只能用延迟处理

<template>
  <div>
    <div v-if="!state"
         style="min-height: 28px"
         @click="edit">
      <div v-if="showLabel"
           style="float: left;">
        <div v-show="item[props.value]==row[name]"
             v-for="(item,index) in columnShowList"
             :key="index">

          {{showAllLevels?item.allLabel : item[props.label]}}

        </div>

      </div>
      <div style="float: left;"
           v-else>{{ row[name] }}

      </div>
      <i class="el-icon-edit"
         v-if="!disabled"
         style="float: left;line-height:24px;padding-left: 5px;color: #409EFF;"></i>
    </div>
    <div v-else
         class="cell">
      <!-- <el-select v-model="value"
                   ref="ediTableSelect"
                   size="mini"
                   class="filter"
                   remote
                   filterable
                   @blur="check"
                   :loading="loading"
                   @visible-change="remoteMethod"
                   placeholder="请选择">
          <el-option v-for="(item,index) in columnList"
                     :key="index"
                     :label="selectSetting.label?item[selectSetting.label]:item"
                     :value="selectSetting.value?item[selectSetting.value]:item">
          </el-option>
        </el-select> -->

      <el-cascader :loading="loading"
                   ref="ediTableCascader"
                   size="mini"
                   v-bind="$attrs"
                   v-on="$listeners"
                   filterable
                   clearable
                   v-model="value"
                   @active-item-change="handleActiveItemChange"
                   :options="columnList"
                   :props="props"
                   @focus="focus"
                   @visible-change="remoteMethod"
                   @blur="blur"
                   @change="handleChange"
                   placeholder="请选择"></el-cascader>
    </div>

  </div>

</template>
      
      <script>
export default {
  props: {
    index: {
      type: Number,
    },
    row: {
      type: Object,
    },
    name: {
      type: String,
    },
    showAllLevels: {
      type: Boolean,
      default: false,
    },
    columnList: {
      type: [Array, null],
    },
    loading: {
      type: Boolean,
    },
    showLabel: {
      type: Boolean,
      default: false,
    },
    props: {
      type: Object,
    },
    disabled: {
      type: Boolean,
      default: false,
    },
    valueFormat: {
      type: Array,
    },
    // selectSetting: {
    //   type: Object,
    //   default: {
    //     label: `label`,
    //     value: `value`,
    //   },
    // },
  },
  data() {
    return {
      state: false,
      value: '',
      columnShowList: [],
      popper: false,
      blurTimeout: true,
    }
  },
  computed: {},
  watch: {
    row: {
      immediate: true,
      deep: true,
      handler(newVal) {
        let value = []
        console.log(newVal, this.name, newVal[this.name], 2222222)
        if (this.valueFormat) {
          for (const item of this.valueFormat) {
            if (newVal[item] && newVal[item] != '') {
              // console.log(newVal[item],item,'itemitem');
              value.push(newVal[item])
            }
          }
        } else {
          if (this.props.emitPath) {
            value.push(newVal[this.name])
          } else {
            value = newVal[this.name]
          }
        }

        this.value = value
      },
    },
    columnList: {
      handler(newval) {
        this.columnShowList = this.setShowLabel(newval)
        // this.columnList.forEach((ele) => {
        //   ele.allLabel = ele[this.props.label]
        //   this.columnShowList.push(ele)

        //   if (ele[this.props.children] && ele[this.props.children].length > 0) {
        //     ele[this.props.children].forEach((item) => {
        //       item.allLabel =
        //         ele[this.props.label] + '/' + item[this.props.label]
        //       this.columnShowList.push(item)
        //     })
        //   }
        // })
        // console.log(this.columnShowList, 'columnShowList')
      },
      deep: true,
      immediate: true,
    },
  },
  methods: {
    setShowLabel(list, parent) {
      let res = []
      list.forEach((ele) => {
        ele.allLabel = parent
          ? parent.allLabel + '/' + ele[this.props.label]
          : ele[this.props.label]
        res.push(ele)

        if (ele[this.props.children] && ele[this.props.children].length > 0) {
          // ele[this.props.children].forEach((item) => {
          res.push(...this.setShowLabel(ele[this.props.children], ele))
          //   item.allLabel =
          //     ele[this.props.label] + '/' + item[this.props.label]
          //   this.columnShowList.push(item)
          // })
        }
      })
      return res
    },
    handleActiveItemChange(value) {
      console.log(value, 'handleActiveItemChange')
    },
    edit() {
      if (!this.disabled) {
        this.state = true
        this.$nextTick(() => {
          console.log(this.$refs.ediTableCascader.$children, this.$refs.input)
          // setTimeout(() => {
          // this.$refs['ediTableCascader'].handleFocus()
          this.$refs.ediTableCascader.$children[0].focus()
          this.$refs.ediTableCascader.toggleDropDownVisible()
          // this.$refs.ediTableCascader.$children[2].focus()
          // },500)
          // this.$refs.ediTableCascader.handleFocus()
          // this.$refs.ediTableCascader.focus()
        })
      }
    },
    focus(e) {
      console.log(1111, e)
    },
    handleChange() {
      console.log(1111)
      this.$nextTick(() => {
        this.check()
      })
    },
    blur(el) {
      // 搜索之后的选择会触发两次blur,并且第二次的popper为false
    //   console.log(this.blurTimeout, this.popper,this.value, 'this.state')

      if (this.blurTimeout) {
        this.blurTimeout = false
        console.log(this.blurTimeout, this.state, 'this.state2222222')
          setTimeout(() => {
            console.log(this.blurTimeout, this.state, 'setTimeout')
            this.blurTimeout = true
          }, 400)
        if (!this.popper) {
          this.state = false
          

        }
      }
      // 设置新的定时器,延迟执行真正的处理逻辑
    },
    check() {
      // console.log(11111);
      setTimeout(() => {
        const itemList = this.$refs.ediTableCascader.getCheckedNodes()
        const item = itemList.map((ele) => {
          //
          return ele.data
        })
        //   console.log(itemList);
        //   console.log(item,itemList);
        this.$emit('change', {
          value: this.value,
          index: this.index,
          name: this.name,
          row: this.row,
          item: item[0],
        })
        this.state = false
        // console.log(this.state);
      }, 100)
    },
    remoteMethod(value) {
      // console.log(222222);
      this.popper = value
      if (value) {
        this.$emit('remote-method', {
          index: this.index,
          row: this.row,
          name: this.name,
        })
      } else {
        this.blur()
      }
    },
  },
}
</script>
      
      <style scoped>
</style>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值