昨天收到一个新的需求,需要选择地址,因此就要做一个省市区三级联动的组件来使用,在网上找了一些资源,然后进行了尝试,没想到就这么成功了!要记录一下方便后续使用。

效果如下:

 下面就记录一下代码叭!

一、 封装vue组件

<!-- 地址选择 & 省市区三级联动 -->
<template>
  <el-form ref="form" :model="form" label-width="120px">
    <el-row>
      <el-select v-model="form.province" placeholder="请选择省" @change="changePro">
        <el-option v-for="item in addressData" :key="item.code" :label="item.name" :value="item.name">
        </el-option>
      </el-select>
      <el-select v-model="form.city" placeholder="请选择市" @change="changeCity">
        <el-option v-for="item in cityData" :key="item.code" :label="item.name" :value="item.name">
        </el-option>
      </el-select>
      <el-select v-model="form.district" placeholder="请选择区" @change="changeArea">
        <el-option v-for="item in areaData" :key="item.code" :label="item.name" :value="item.name">
        </el-option>
      </el-select>
      <el-input placeholder="详细地址" v-model="form.detail" style="width:200px;" clearable></el-input>
    </el-row>
    <!-- <h3>测试当前选中地址:{{result}}</h3> -->
  </el-form>
</template>
 
<script>
import address from "@/utils/address/address.json"; //全国省市区街道数据
export default {
  data() {
    return {
      //  省数据
      addressData: [],
      //  市数据
      cityData: [],
      // 区数据
      areaData: [],
    };
  },
  props: {
    // 街道数据
    form: {
      province: "",
      // 市
      city: "",
      // 区
      district: "",
      //详细地址
      detail: "",
    }
  },
  created() {
    // 省份数据初始化
    this.addressData = address;
    // console.log("this.form",this.form)

    if (this.form.province != "") {
      let cityData = this.addressData.filter(item => item.name == this.form.province)
      if (cityData.length) {
        this.cityData = cityData[0].children

        let areaData = this.cityData.filter(item => item.name == this.form.city)
        if (areaData.length) {
          this.areaData = areaData[0].children
        }
      }
    }
  },
  computed: {
    //选择结果
    result() {
      if (!this.form.district) {
        return ''
      } else if (this.form.district && this.form.detail) {
        return '' + this.form.province + "," + this.form.city + "," + this.form.district + "," + this.form.detail
      } else {
        return '' + this.form.province + "," + this.form.city + "," + this.form.district
      }
    }
  },
  methods: {
    reset() {
      this.form = {
        // 省
        province: "",
        // 市
        city: "",
        // 区
        district: "",
        //详细地址
        detail: "",
      }
    },
    // 省份更改
    changePro(e) {
      // 从省中过滤出市的数据
      this.cityData = this.addressData.filter((item) => {
        return item.name == e;
      })[0].children;
      // 省发生改变的时候 清空输入框市区街道的内容

      this.form.district = "";
      this.form.city = this.cityData[0].name;
      // 省发生更改时 该表空区街道数据的内容
      this.areaData = this.cityData[0].children;
      this.form.district = this.areaData[0].name
    },
    // 市更改
    changeCity(e) {
      // 获取到区的数据
      this.areaData = this.cityData.filter(
        (item) => item.name == e
      )[0].children;
      // 清空数据后面对应数组的数据
      this.form.district = this.areaData[0].name;
    },
    // 区更改
    changeArea(e) {
      let temp = this.areaData.filter((item) => item.name == e);
      // 获取到区的code码
      this.form.regionalNumber = temp[0].code;
      // 获取到街道的数据
      this.jdData = this.areaData.filter((item) => item.name == e)[0].children;
    },
  },
};
</script>

<style lang="scss" rel="stylesheet/scss" scoped>
.el-row {
  display: inline;
}

.el-row {
  display: inline-flex;
  flex: auto;

  .el-select {
    margin: 0 20px 0 0;
    width: 122px;
  }
}
</style>

二、在页面中引用

<el-form-item label="联系地址" prop="address" v-model="ruleForm.address">
    <checkAddress ref="address" v-model="ruleForm.address" :form="ruleForm.address" />
</el-form-item>
    data() {
        var validatePass = (rule, value, callback) => {
            
            if (this.ruleForm.address.province == '' || this.ruleForm.address.detail == '') {
                callback(new Error('请输入完整地址'));
            }
            callback();
        };
        return {
            supplierList: [],
  
            direction: 'btt',
            ifCreate: false,
            ruleForm: {
                address: {
                    // 省
                    province: "",
                    // 市
                    city: "",
                    // 区
                    district: "",
                    //详细地址
                    detail: "",
                }
            },
            rules: {
                address: [
                    { required: true ,validator: validatePass, trigger: 'blur' },
                ]
            }
        }
    },
  watch: {
    ruleForm: {
      // deep:true,
      handler() {
        this.ruleForm.address = this.$refs.address.form
        console.log(this.ruleForm.address)
      }
    }
  },

三、去网上找个Address.json文件放进去就好了

后面因为需要动态绑定,以及处理回显问题,就需要进行一些其它的处理:

解决elementui 的省市区级联选择器数据不回显问题icon-default.png?t=N7T8http://t.csdn.cn/lVPn6

考虑到有很多小伙伴需要这个东西,我把address文件放在这里啦,需要自取哦!

链接:https://pan.baidu.com/s/1iuLf1QfE55ZulIeF5Ch9dQ?pwd=0710 
提取码:0710 

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐