JAreaLinkage.vue 3.6 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
<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>