vue中el-select多级联动和清空

6,679 阅读1分钟

说明

在多级联动时,只有选择了前面的选项,才会请求的后面选项列表,如果用户重新选择前面的选项,会清空掉后面关联的选项值并重新请求选项列表

监听父选项的visible-change属性变化,用于区分是用户手动触发还是编辑回显时触发的,可以实现如下功能

  • 用户手动触发:根据情况清空关联的选项值

  • 编辑回显时:不会清空关联的选项值

  • 适用场景: 关联的el-select都在同一个组件中,不能分开在不同组件中,否则该方案无效

HTML

<template>
  <el-form ref="postForm" :model="postForm" label-width="120px">
    <el-form-item label="area">
      <el-select v-model="postForm.area" placeholder="请选择大区" @visible-change="handleSelectVisibleChange">
        <el-option 
          v-for="item in areaOptions" 
          :key="item.id" 
          :label="item.name" 
          :value="item.id">
        </el-option>
      </el-select>
    </el-form-item>

    <el-form-item label="second_area">
      <el-select v-model="postForm.second_area" placeholder="请选择二级区" @visible-change="handleSelectVisibleChange">
        <el-option 
          v-for="item in secondOptions" 
          :key="item.id" 
          :label="item.name" 
          :value="item.id">
        </el-option>
      </el-select>
    </el-form-item>

    <el-form-item label="service">
      <el-select v-model="postForm.service" placeholder="请选择服务器" @visible-change="handleSelectVisibleChange">
        <el-option 
          v-for="item in serviceOptions" 
          :key="item.id" 
          :label="item.name" 
          :value="item.id">
        </el-option>
      </el-select>
    </el-form-item>

  </el-form>
</template>

JS

  const postForm = {
    name: '',
    area: '',
    second_area: '',
    service: ''
  }
  export default {
    props: {
      isEdit: {
        type: Boolean,
        default: false
      }
    },
    data() {
      return {
        postForm: Object.assign({}, postForm),
        areaOptions: [],
        secondOptions: [],
        serviceOptions: [],
        isSelectVisible: false // 是否是下拉框出现触发
      }
    },
    watch: {
      'postForm.area'(newVal, oldVal) {
        if(this.isSelectVisible) {
          // 清空关联的子选项值
          this.postForm.second_area = ''
        }
        if(!isEmpty(newVal)) {
          // 如果用户已经重新选择,重新请求子选项列表
          this.getSecondAreaOptions(newVal)
        }
      },
      'postForm.second_area'(newVal, oldVal) {
        if(this.isSelectVisible) {
          this.postForm.service = ''
        }
        if(!isEmpty(newVal)) {
          this.getServiceOptions(newVal)
        }
      }
    },
    created() {
      this.getAreaOptions()
      if (this.isEdit) {
        const id = this.$route.query.id
        this.postForm.id = id
        this.getDetail(this.postForm.id)
      }
    },
    methods: {
      getAreaOptions() {
        getAreaOptions()
        .then(res => {
          this.areaOptions = res.data.list
        })
      },
      getServiceOptions(id) {
        getServiceOptions(id)
        .then(res => {
          this.serviceOptions = res.data.list
        })
      },
      getSecondAreaOptions(id) {
        getSecondAreaOptions(id)
        .then(res => {
          this.secondOptions = res.data.list
        })
      },
      handleSelectVisibleChange(v) {
        this.isSelectVisible = v
      },
      getDetail(id) {
        return new Promise((resolve, reject) => {
          getPositionDetail(id)
          .then(res => {
            this.postForm = res.data
            resolve(res.data)
          })
          .catch(err => {
            reject(err)
          })
        })
      }
    }
  }
</script>

工具函数isEmpty

function isEmpty(v) {
  if (v === '' || v === undefined || v === null) {
    return true
  }

  if (typeof v === 'object') {
    if (Array.isArray(v)) {
      return v.length === 0
    } else {
      return Object.keys(v).length === 0
    }
  }
  return false
}