JAreaLinkage.vue 3.39 KB
<template>
  <div class="j-area-linkage">
    <div v-if="reloading">
      <span> Reloading... </span>
    </div>
    <area-cascader
      v-else-if="_type === enums.type[0]"
      :value="innerValue"
      :data="pcaa"
      :level="1"
      :style="{width}"
      v-bind="$attrs"
      v-on="_listeners"
      @change="handleChange"
    />
    <area-select
      v-else-if="_type === enums.type[1]"
      :value="innerValue"
      :data="pcaa"
      :level="2"
      v-bind="$attrs"
      v-on="_listeners"
      @change="handleChange"
    />
    <div v-else>
      <span style="color:red;"> Bad type value: {{ _type }}</span>
    </div>
  </div>
</template>

<script>
import Area from '@/components/_util/Area'

export default {
  name: 'JAreaLinkage',
  props: {
    value: {
      type: String,
      required: false
    },
    // 组件的类型,可选值:
    // select 下拉样式
    // cascader 级联样式(默认)
    type: {
      type: String,
      default: 'cascader'
    },
    width: {
      type: String,
      default: '100%'
    }
  },
  data() {
    return {
      pcaa: this.$Jpcaa,
      innerValue: [],
      usedListeners: ['change'],
      enums: {
        type: ['cascader', 'select']
      },
      reloading: false,
      areaData: ''
    }
  },
  computed: {
    _listeners() {
      let listeners = {...this.$listeners}
      // 去掉已使用的事件,防止冲突
      this.usedListeners.forEach(key => {
        delete listeners[key]
      })
      return listeners
    },
    _type() {
      if (this.enums.type.includes(this.type)) {
        return this.type
      } else {
        console.error(`JAreaLinkage的type属性只能接收指定的值(${this.enums.type.join('|')})`)
        return this.enums.type[0]
      }
    },
  },
  watch: {
    value: {
      immediate: true,
      handler() {
        this.loadDataByValue(this.value)
      }
    },
  },
  created() {
    this.initAreaData();
  },
  methods: {

    /** 重新加载组件 */
    reload() {
      this.reloading = true
      this.$nextTick(() => this.reloading = false)
    },

    /** 通过 value 反推 options */
    loadDataByValue(value) {
      if (!value || value.length === 0) {
        this.innerValue = []
      } else {
        this.initAreaData()
        let arr = this.areaData.getRealCode(value)
        this.innerValue = arr
      }
      this.reload()
    },
    /** 通过地区code获取子级 */
    loadDataByCode(value) {
      let options = []
      let data = this.pcaa[value]
      if (data) {
        for (let key in data) {
          if (data.hasOwnProperty(key)) {
            options.push({value: key, label: data[key],})
          }
        }
        return options
      } else {
        return []
      }
    },
    /** 判断是否有子节点 */
    hasChildren(options) {
      options.forEach(option => {
        let data = this.loadDataByCode(option.value)
        option.isLeaf = data.length === 0
      })
    },
    handleChange(values) {
      let value = values[values.length - 1]
      this.$emit('change', value)
    },
    initAreaData() {
      if (!this.areaData) {
        this.areaData = new Area(this.$Jpcaa);
      }
    },

  },
  model: {prop: 'value', event: 'change'},
}
</script>

<style lang="less" scoped>
.j-area-linkage {
  height: 40px;

  /deep/ .area-cascader-wrap .area-select {
    width: 100%;
  }

  /deep/ .area-select .area-selected-trigger {
    line-height: 1.15;
  }
}

</style>