Просмотр исходного кода

feat: 提交省市县三级联动下拉

xyh 5 месяцев назад
Родитель
Сommit
495a84de5a
1 измененных файлов с 119 добавлено и 0 удалено
  1. 119 0
      src/components/AreaCascader/index.vue

+ 119 - 0
src/components/AreaCascader/index.vue

@@ -0,0 +1,119 @@
+<script>
+import { getCity } from '@/api/points/rules_api';
+export default {
+  name: 'AreaCascader',
+  props: {
+    value: {
+      type: Array,
+      default: () => []
+    },
+    placeholder: {
+      type: String,
+      default: '请选择地区'
+    }
+  },
+  data() {
+    return {
+      options: [],
+      loading: false,
+      localValue: this.value // 本地存储 value
+    };
+  },
+  watch: {
+    value: {
+      handler(newVal) {
+        this.localValue = newVal;
+      },
+      deep: true
+    },
+    localValue: {
+      handler(newVal) {
+        this.$emit('input', newVal);
+      },
+      deep: true
+    }
+  },
+
+  methods: {
+    // 处理地区数据的方法
+    processAreaData(data, level) {
+      return data.map(item => ({
+        value: item.code,
+        label: item.name,
+        children: level < 3 ? [] : undefined,
+        leaf: level === 3 // 标记为叶子节点,不显示展开箭头
+      }));
+    },
+    
+    // 加载地区数据的统一方法
+    async loadAreaData(parentCode = 0, level, resolve = null) {
+      if (level === 1) {
+        this.loading = true;
+      }
+      
+      try {
+        const response = await getCity({ level, parentCode });
+        const processedData = this.processAreaData(response.data, level);
+        
+        if (level === 1) {
+          // 初始加载省份数据
+          this.options = processedData;
+        } else if (resolve) {
+          // 懒加载子地区数据
+          resolve(processedData);
+        }
+      } catch (error) {
+        console.error('获取地区数据失败:', error);
+        if (resolve) {
+          resolve([]);
+        }
+      } finally {
+        if (level === 1) {
+          this.loading = false;
+        }
+      }
+    },
+    
+    // 懒加载子地区数据
+    loadChildren(node, resolve) {
+      if (node.level === 0) {
+        // 省份节点,加载城市数据
+        this.loadAreaData(node.value, 1, resolve);
+      } else if (node.level === 1) {
+        // 城市节点,加载区县数据
+        this.loadAreaData(node.value, 2, resolve);
+      } else if (node.level === 2) {
+        // 城市节点,加载区县数据
+        this.loadAreaData(node.value, 3, resolve);
+      } else {
+        resolve([]);
+      }
+    },
+    
+    // 处理选中变化
+    handleChange(value, selectedOptions) {
+      this.$emit('input', value);
+      this.$emit('change', value, selectedOptions);
+    }
+  }
+};
+</script>
+
+<template>
+  <el-cascader
+    v-model="localValue"
+    :options="options"
+    :props="{
+      checkStrictly: false,
+      expandTrigger: 'click',
+      lazy: true,
+      lazyLoad: loadChildren
+    }"
+    :placeholder="placeholder"
+    @change="handleChange"
+    :loading="loading"
+  ></el-cascader>
+</template>
+
+<style scoped>
+</style>