|
|
@@ -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>
|