| <template> | 
|   <Category :category="provinceList" @change="change"> | 
|     <CategoryPane | 
|       :max="max" | 
|       :categoryChild="categoryChild" | 
|       :multiple="multiple" | 
|       v-model="state.preModelValue" | 
|     > | 
|     </CategoryPane> | 
|   </Category> | 
|   <div class="bole-menu-item__footer"> | 
|     <div class="bole-menu-item__button-wrapper"> | 
|       <nut-button | 
|         shape="square" | 
|         class="dark-btn" | 
|         color="#E9E8E8" | 
|         type="primary" | 
|         @click="handleCancel" | 
|       > | 
|         取消 | 
|       </nut-button> | 
|       <nut-button shape="square" type="primary" @click="handleConfirm">确认</nut-button> | 
|     </div> | 
|   </div> | 
| </template> | 
|   | 
| <script setup lang="ts"> | 
| import { useAllAreaList, useAreaTree } from '@12333/hooks'; | 
| import Category from './Category.vue'; | 
| import CategoryPane from './CategoryPane.vue'; | 
| import { reactive, computed, watch } from 'vue'; | 
|   | 
| defineOptions({ | 
|   name: 'AreaTreeSelect', | 
| }); | 
|   | 
| type Props = { | 
|   modelValue: number[]; | 
|   multiple?: boolean; | 
|   max?: number; | 
| }; | 
|   | 
| const props = withDefaults(defineProps<Props>(), { | 
|   multiple: true, | 
| }); | 
|   | 
| const emit = defineEmits<{ | 
|   (e: 'update:modelValue', value: number[]): void; | 
|   (e: 'close'): void; | 
| }>(); | 
|   | 
| // const innerModelValue = computed({ | 
| //   get() { | 
| //     return props.modelValue; | 
| //   }, | 
| //   set(val) { | 
| //     emit('update:modelValue', val); | 
| //   }, | 
| // }); | 
|   | 
| const { areaTree } = useAreaTree(); | 
|   | 
| const state = reactive({ | 
|   provinceIndex: 0, | 
|   preModelValue: props.modelValue, | 
| }); | 
|   | 
| const provinceList = computed(() => areaTree.value.map((x) => ({ ...x, name: x.areaName }))); | 
| const categoryChild = computed(() => { | 
|   if (!provinceList.value.length) { | 
|     return []; | 
|   } | 
|   return provinceList.value[state.provinceIndex].children.map((x) => ({ | 
|     ...x, | 
|     name: x.areaName, | 
|     value: x.areaCode, | 
|   })); | 
| }); | 
|   | 
| const change = (index: number) => { | 
|   state.provinceIndex = index; | 
| }; | 
|   | 
| function handleCancel() { | 
|   emit('close'); | 
|   state.preModelValue = []; | 
|   emit('update:modelValue', []); | 
| } | 
|   | 
| function handleConfirm() { | 
|   emit('close'); | 
|   emit('update:modelValue', [...state.preModelValue]); | 
| } | 
| </script> | 
|   | 
| <style lang="scss"> | 
| @import '@/styles/common.scss'; | 
|   | 
| // .nut-menu-item__content { | 
| .nut-category { | 
|   height: 560rpx; | 
|   | 
|   .nut-category__cateList { | 
|     height: 100%; | 
|   | 
|     & > .h5-div { | 
|       height: 100%; | 
|       overflow-y: auto; | 
|     } | 
|   | 
|     .nut-category__cateList-scroll { | 
|       height: 100%; | 
|       width: auto; | 
|     } | 
|   } | 
|   | 
|   .nut-category-pane { | 
|     height: 100%; | 
|     overflow-y: auto; | 
|     flex: 1; | 
|     min-width: 0; | 
|   } | 
| } | 
|   | 
| // } | 
|   | 
| .bole-menu-item__footer { | 
|   padding: 30px; | 
|   background-color: #fff; | 
|   box-shadow: 0px -5px 10px 0px rgba(0, 0, 0, 0.03); | 
|   position: relative; | 
|   | 
|   .bole-menu-item__button-wrapper { | 
|     display: flex; | 
|     margin: 0 -10rpx; | 
|   | 
|     .nut-button { | 
|       flex: 1; | 
|       margin: 0 10rpx; | 
|       border-radius: 10rpx; | 
|       font-size: 32rpx; | 
|     } | 
|   } | 
| } | 
| </style> |