封装一个省市区的筛选组件

时间:2024-11-15 15:37:10

筛选功能:只能单选(如需多选需要添加show-checkbox多选框属性,选中省传递省的ID,选中市传递省、市的ID, 选中区传递省市区的ID

 

父组件:

 <el-form-item>
   <div style="width: 240px;padding-left: 20px;border-radius: 4px;color: #c0bdbd;
    border: 1px solid #d4cece;height: 32px;line-height: 32px;"@click="OrderAreabtn">
    {{ fullAddress }}
  </div>
  <OrderArea v-if="OrderAreaVisible" ref="addOrUpdate" @refreshDataList="getDataList"> 
  </OrderArea>
</el-form-item>
import OrderArea from "./orderarea.vue";
components: { OrderArea },
OrderAreaVisible: false,
fullAddress: "请选择地区",
getDataList(row) {
      console.log("子组件传递回来的数据", row);
},
OrderAreabtn() {
      this.OrderAreaVisible = true;
      this.$nextTick(() => {
        this.$refs.addOrUpdate.init();
      });
},

子组件:

<template>
  <div class="shop-transcity-add-or-update">
    <el-dialog
      :modal="false"
      title="请选择地区"
      :close-on-click-modal="false"
      :visible.sync="visible"
    >
      <el-form
        :model="dataForm"
        ref="dataForm"
        @keyup.enter.native="dataFormSubmit()"
        label-width="180px"
        style="height: 400px"
      >
        <el-scrollbar style="height: 100%">
          <el-form-item size="mini">
            <el-tree
              :data="menuList"
              node-key="areaId"
              ref="menuListTree"
              :props="menuListTreeProps"
              :show-checkbox="false"
              :check-strictly="true"
              @node-click="handleNodeClick"
            >
            </el-tree>
          </el-form-item>
        </el-scrollbar>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="visible = false">取消</el-button>
        <el-button type="primary" @click="dataFormSubmit()">确定</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
let treeDataTranslate = (data, id = "id", pid = "parentId") => {
  var res = [];
  var temp = {};
  for (var i = 0; i < data.length; i++) {
    temp[data[i][id]] = data[i];
  }
  for (var k = 0; k < data.length; k++) {
    if (temp[data[k][pid]] && data[k][id] !== data[k][pid]) {
      if (!temp[data[k][pid]]["children"]) {
        temp[data[k][pid]]["children"] = [];
      }
      if (!temp[data[k][pid]]["_level"]) {
        temp[data[k][pid]]["_level"] = 1;
      }
      data[k]["_level"] = temp[data[k][pid]]._level + 1;
      temp[data[k][pid]]["children"].push(data[k]);
    } else {
      res.push(data[k]);
    }
  }
  return res;
};
export default {
  data() {
    return {
      visible: false,
      menuList: [],
      menuListTreeProps: {
        children: "children",
        label: "areaName",
        id: "areaId",
      },
      dataForm: {
        province: null,
        area: null,
        city: null,
        fullAddress: "",
      },
    };
  },
  methods: {
    init() {
      this.visible = true;
      this.request({
        url: "/xxx/area/list",
        method: "get",
        params: {
          pageNum: 1,
          pageSize: 1000000,
        },
      }).then((res) => {
       //treeDataTranslate()处理数据为树结构,如果你的数据已经是树结构则可直接赋值
        this.menuList = treeDataTranslate(res.rows, "areaId", "parentId");
      });
    },

    getAreaNameById(areaId) {
      return this.findAreaName(this.menuList, areaId);
    },
    findAreaName(nodes, areaId) {
      for (let node of nodes) {
        if (node.areaId === areaId) {
          return node.areaName;
        }
        if (node.children && node.children.length > 0) {
          const foundName = this.findAreaName(node.children, areaId);
          if (foundName) {
            return foundName;
          }
        }
      }
      return null;
    },

    // 获取祖父节点ID
    getGrandparentId(node) {
      const parentNode = this.findParentNode(this.menuList, node.areaId);
      if (parentNode) {
        const grandparentNode = this.findParentNode(
          this.menuList,
          parentNode.areaId
        );
        return grandparentNode ? grandparentNode.areaId : null;
      }
      return null;
    },
    findParentNode(nodes, areaId) {
      for (let node of nodes) {
        if (node.children && node.children.length > 0) {
          for (let child of node.children) {
            if (child.areaId === areaId) {
              return node;
            }
          }
          const foundNode = this.findParentNode(node.children, areaId);
          if (foundNode) {
            return foundNode;
          }
        }
      }
      return null;
    },

    handleNodeClick(node) {
      //选中省
      if (node.level == 1) {
        this.dataForm.province = node.areaId;
        this.dataForm.city = null;
        this.dataForm.area = null;
        this.dataForm.fullAddress = node.areaName;
      }
      //选中市
      if (node.level == 2) {
        this.dataForm.province = node.parentId;
        this.dataForm.city = node.areaId;
        this.dataForm.area = null;
      }
      //选中区
      if (node.level == 3) {
        const grandparentId = this.getGrandparentId(node);
        if (grandparentId) {
          this.dataForm.province = grandparentId;
        } else {
          console.log("没有找到祖父节点");
        }

        if (node.children && node.children.length > 0) {
          this.dataForm.city = node.areaId;
          this.dataForm.area = null;
        } else {
          this.dataForm.city = node.parentId;
          this.dataForm.area = node.areaId;
        }
      }
    },
    // 表单提交
    dataFormSubmit() {
      console.log(
        "选中的省市区ID:",
        this.dataForm.province,
        this.dataForm.city,
        this.dataForm.area
      );
      const provinceName = this.getAreaNameById(this.dataForm.province);
      const cityName = this.getAreaNameById(this.dataForm.city);
      const districtName = this.getAreaNameById(this.dataForm.area);

      this.dataForm.fullAddress = provinceName; //选中省
      if (cityName) {
        //选中市
        this.dataForm.fullAddress = `${provinceName} ${cityName}`;
      }
      if (districtName) {
        //选中区
        this.dataForm.fullAddress = `${provinceName} ${cityName} ${districtName}`;
      }
      console.log("选中的省市区名称:", this.dataForm.fullAddress);

      this.$emit("refreshDataList", this.dataForm);
      this.visible = false;
    },
  },
};
</script>

<style lang="scss">
.shop-transcity-add-or-update {
  .el-scrollbar__wrap {
    overflow-x: hidden;
  }
}
</style>