Vue省市区组件

 组件如下:

<template>
  <div :class="wrapper">
    <el-select
      v-model="currentProvince"
      :disabled="disabled || provinceDisabled"
      placeholder="省"
      filterable
      @change="getCities"
    >
      <template v-if="typeof currentProvince=='number'">
        <el-option
          v-for="(item, index) in provinces"
          :key="index"
          :value="item.code"
          :label="item.name"
        />
      </template>
      <template v-else>
        <el-option
          v-for="(item, index) in provinces"
          :key="index"
          :value="item.code"
          :label="item.name"
        />
      </template>
    </el-select>
    <template v-if="!onlyProvince">
      <el-select
        v-model="currentCity"
        :disabled="disabled || cityDisabled"
        placeholder="市"
        filterable
        @change="getAreas"
      >
        <el-option
          v-for="(item, index) in cities"
          :key="index"
          :value="item.code"
          :label="item.name"
        />
      </el-select>
      <el-select
        v-if="!hideArea"
        v-model="currentArea"
        :disabled="disabled || areaDisabled"
        filterable
        placeholder="区"
      >
        <el-option
          v-for="(item, index) in areas"
          :key="index"
          :value="item.code"
          :label="item.name"
        />
      </el-select>
    </template>
  </div>
</template>

<script>
import DISTRICTS from './districts'   //这个文件是省市区数据源

export default {
  name: 'VDistpicker',
  props: {
    province: { type: [String, Number], default: '' },
    city: { type: [String, Number], default: '' },
    area: { type: [String, Number], default: '' },
    hideArea: { type: Boolean, default: false },
    onlyProvince: { type: Boolean, default: false },
    disabled: { type: Boolean, default: false },
    provinceDisabled: { type: Boolean, default: false },
    cityDisabled: { type: Boolean, default: false },
    areaDisabled: { type: Boolean, default: false },
    wrapper: { type: String, default: 'distpicker-address-wrapper' }
  },
  data() {
    return {
      provinces: [],
      cities: [],
      areas: [],
      currentProvince: '',
      currentCity: '',
      currentArea: ''
    }
  },
  watch: {
    currentProvince(value) {
      this.$emit('province', this.setData(value, this.provinces))
      if (this.onlyProvince) this.emit('selected')
    },
    currentCity(value) {
      this.$emit('city', this.setData(value, this.cities))
      if (this.hideArea) this.emit('selected')
    },
    currentArea(value) {
      this.$emit('area', this.setData(value, this.areas))
      this.emit('selected')
    },
    province(value) {
      this.currentProvince = value
      this.cities = this.getDataList(this.currentProvince, this.provinces)
    },
    city(value) {
      this.currentCity = value
      this.areas = this.getDataList(this.currentCity, this.cities)
    },
    area(value) {
      this.currentArea = value
    }
  },
  created() {
    this.provinces = DISTRICTS
    this.currentProvince = this.getNameValue(this.province, this.provinces)
    this.cities = this.province
      ? this.getDataList(this.province, this.provinces)
      : []
    this.currentCity = this.getNameValue(this.city, this.cities)
    this.areas = this.city ? this.getDataList(this.city, this.cities) : []
    this.currentArea = this.getNameValue(this.area, this.areas)
  },
  methods: {
    setData(value, list) {
      const valueObj = list ? list.find(item => item.code === Number(value) || item.name === value) : null
      return valueObj
        ? {
          code: valueObj.code,
          value: valueObj.name
        }
        : {
          code: '',
          value: ''
        }
    },

    emit(name) {
      const data = {
        province: this.setData(this.currentProvince, this.provinces)
      }

      if (!this.onlyProvince) {
        this.$set(data, 'city', this.setData(this.currentCity, this.cities))
      }

      if (!this.onlyProvince || this.hideArea) {
        this.$set(data, 'area', this.setData(this.currentArea, this.areas))
      }

      this.$emit(name, data)
    },

    getCities() {
      this.currentCity = ''
      this.currentArea = ''
      this.cities = this.getDataList(this.currentProvince, this.provinces)
      this.cleanList('areas')
      if (this.cities.length === 0) {
        this.emit('selected')
      }
    },

    getAreas() {
      this.currentArea = ''
      this.areas = this.getDataList(this.currentCity, this.cities)
      if (this.areas.length === 0) {
        this.emit('selected')
      }
    },

    /**
     * 获取数据信息
     * value code/name
     * list 上一级数据
     */
    getDataList(val, list) {
      const value = Number(val) || val
      const isCode = typeof value === 'number'
      if (list && list.length) {
        for (let index = 0; index < list.length; index++) {
          const item = list[index]
          if (
            (isCode && item.code === value) ||
          (!isCode && item.name === value)
          ) {
            return item.children
          }
        }
      }
    },

    /**
     * 获取名称值
     * value code/name
     * list 当前类型数据
     */
    getNameValue(val, list) {
      const value = Number(val) || val
      if (!value) return value
      if (typeof value === 'number') {
        if (list && list.length) {
          for (let index = 0; index < list.length; index++) {
            const item = list[index]
            if (item.code === value) {
              return item.name
            }
          }
        }
      }
      return value
    },

    cleanList(name) {
      this[name] = []
    }
  }
}
</script>

<style lang="scss">
.distpicker-address-wrapper {
  color: #9caebf;

  .el-select {
    width: 30%;
  }
}
</style>

使用:

            <distpicker
              :province="formData.belongProvince"
              :city="formData.belongCity"
              :area="formData.belongArea"
              class="city"
              @province="selectProvince($event)"
              @city="selectCity($event)"
              @area="selectArea($event)"
            />


    /**
     * 省市区处理
     *    code 为数字
     *    value 为名
     **/
    selectProvince(data, item, index) {
      this.$set(this.formData, 'belongProvince', data.code)
      this.$set(this.formData, 'province', data.value)
    },

    selectCity(data, item, index) {
      this.$set(this.formData, 'areaCode', data.code)
      this.$set(this.formData, 'belongCity', data.code)
      this.$set(this.formData, 'city', data.value)
    },

    selectArea(data, item, index) {
      this.$set(this.formData, 'areaCode', data.code)
      this.$set(this.formData, 'belongArea', data.code)
      this.$set(this.formData, 'district', data.value)
    },

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值