index.vue 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. <script lang="ts" setup>
  2. import { defineProps, defineEmits, ref, onMounted, watch } from 'vue'
  3. import { CascaderOption } from 'vant'
  4. import { getGridAddress } from '@/api/system'
  5. // 接收父组件传递的 props
  6. const props = defineProps<{
  7. modelValue: boolean
  8. }>()
  9. const emit = defineEmits(['update:modelValue','finish'])
  10. const localShow = ref(props.modelValue) // 本地控制的显示状态
  11. const cascaderValue = ref<string>() // 用于存储级联选择的值
  12. const options = ref<CascaderOption[]>([]) // 用于存储级联选择的选项
  13. // 监听 props 的变化,更新本地状态
  14. watch(
  15. () => props.modelValue,
  16. (newVal) => {
  17. localShow.value = newVal
  18. }
  19. )
  20. // 当弹窗关闭时触发事件,更新父组件的 areaShow
  21. const onClose = () => {
  22. emit('update:modelValue', false)
  23. }
  24. // 当级联选择完成时
  25. const onFinish = (value: any) => {
  26. emit('update:modelValue', false)
  27. emit('finish',value)
  28. }
  29. // 异步加载选项数据
  30. const fieldNames = {
  31. text: 'areaName',
  32. value: 'areaCode',
  33. children: 'childrenRes',
  34. }
  35. // 递归删除最后一级的childrenRes为[]的节点
  36. const deleteEmptyChildren = (data: CascaderOption[]) => {
  37. data.forEach((item) => {
  38. if (item.childrenRes && item.childrenRes.length === 0) {
  39. delete item.childrenRes
  40. }
  41. if (item.childrenRes) {
  42. deleteEmptyChildren(item.childrenRes)
  43. }
  44. })
  45. return data
  46. }
  47. onMounted(async () => {
  48. const { data } = await getGridAddress({ parentCode: '330205', selectMethod: '2' })
  49. options.value = data ? deleteEmptyChildren(data) : []
  50. })
  51. </script>
  52. <template>
  53. <van-popup v-model:show="localShow" round position="bottom">
  54. <van-cascader
  55. v-model="cascaderValue"
  56. title="请选择所在地区"
  57. :options="options"
  58. :field-names="fieldNames"
  59. @close="onClose"
  60. @finish="onFinish"
  61. />
  62. </van-popup>
  63. </template>
  64. <style lang="scss" scoped></style>