ant-design-vue 多选多选并回显 vue3

 文件areaData中北京 一小块

[{"parentCode":"CN","regionCode":"110000","regionName":"北京市","regionLevel":1,"children":[{"parentCode":"110000","regionCode":"110100000000","regionName":"北京市","regionLevel":2,"children":[{"parentCode":"110100000000","regionCode":"110101000000","regionName":"东城区","regionLevel":3,"children":null},{"parentCode":"110100000000","regionCode":"110102000000","regionName":"西城区","regionLevel":3,"children":null},{"parentCode":"110100000000","regionCode":"110105000000","regionName":"朝阳区","regionLevel":3,"children":null},{"parentCode":"110100000000","regionCode":"110106000000","regionName":"丰台区","regionLevel":3,"children":null},{"parentCode":"110100000000","regionCode":"110107000000","regionName":"石景山区","regionLevel":3,"children":null},{"parentCode":"110100000000","regionCode":"110108000000","regionName":"海淀区","regionLevel":3,"children":null},{"parentCode":"110100000000","regionCode":"110109000000","regionName":"门头沟区","regionLevel":3,"children":null},{"parentCode":"110100000000","regionCode":"110111000000","regionName":"房山区","regionLevel":3,"children":null},{"parentCode":"110100000000","regionCode":"110112000000","regionName":"通州区","regionLevel":3,"children":null},{"parentCode":"110100000000","regionCode":"110113000000","regionName":"顺义区","regionLevel":3,"children":null},{"parentCode":"110100000000","regionCode":"110114000000","regionName":"昌平区","regionLevel":3,"children":null},{"parentCode":"110100000000","regionCode":"110115000000","regionName":"大兴区","regionLevel":3,"children":null},{"parentCode":"110100000000","regionCode":"110116000000","regionName":"怀柔区","regionLevel":3,"children":null},{"parentCode":"110100000000","regionCode":"110117000000","regionName":"平谷区","regionLevel":3,"children":null},{"parentCode":"110100000000","regionCode":"110118000000","regionName":"密云区","regionLevel":3,"children":null},{"parentCode":"110100000000","regionCode":"110119000000","regionName":"延庆区","regionLevel":3,"children":null}]}]}]

 组件 duoxuan.vue

​
<script setup lang="ts">
import {ref, onMounted, defineEmits,defineProps} from "vue";
import areaData from '@/assets/json/area.json';
// areaData 数据格式
// {
//   regionCode,
//   regionName,
//   children:[]
//   ...   无用数据
// }
import { Modal } from 'ant-design-vue';
import Zhongxuan from "./zhongxuan.vue";

const value = ref([])
const data = ref([])
const a = ref([])
const visible=ref(true)
const props=defineProps(['curForm_data'])
const emit = defineEmits(['confirmEvent']);
onMounted(() => {
  a.value = shaixuan(areaData)
  huixian()
})

//回显 遍历省市区编号开头 对应再深入遍历
const huixian=()=>{
  console.log(props.curForm_data[0].sele_area_id_array)
  props.curForm_data[0].sele_area_id_array.forEach(item=>{
    a.value.forEach((i)=>{
      if(i.regionCode.slice(0,3)===item.slice(0,3)) {
        i.children.forEach((it)=>{
          if(it.regionCode.slice(3,5)==item.slice(3,5)) {
            it.children.forEach((ite)=>{
              if(item===ite.regionCode){
                if(!it.huixian){
                  it.huixian=[]
                }
                it.huixian.push(ite.regionCode)
                console.log(it.huixian)
              }
            })
          }
        })

      }
    })
  })
}


const handleOk = (e: MouseEvent) => {
  queren()
  visible.value = false;
};


//将数据格式筛选
const shaixuan = (v) => {
  let box1 = []
  v.forEach((item, index) => {
    const box2 = []
    if (item.children) {
      const box3 = shaixuan(item.children)
      box1.push({
        regionCode: item.regionCode,
        regionName: item.regionName,
        children: box3
      })
      return
    }
    box1.push({
      regionCode: item.regionCode,
      regionName: item.regionName
    })

  })
  return box1
}
const itemContent = (obj) => {
  let box = data.value.filter((i) => {
    return i.regionName === obj.regionName
  })
  if (box.length === 0) {
    data.value.push(obj)
  } else {
    data.value.forEach((ite, ind) => {
      if (ite.regionName === obj.regionName) {
        data.value.splice(ind, 1, obj)
      }
    })
  }
}

const queren = () => {
  let deliver_areas = []
  let sele_area_id_array = []
  data.value.forEach((item) => {

    item.value.length > 0 && item.value.forEach((it) => {
      sele_area_id_array.push(it.regionCode)
      deliver_areas.push(it.regionName)
    })

  })
  emit('confirmEvent', {
    deliver_areas: deliver_areas.toString(),
    sele_area_id_array
  })
}


</script>

<template>
<!--  {{a}}-->
<div @click="visible=true">xianshi</div>
  <Modal  width="1000px" style="top: 20px" v-model:visible="visible" title="选择地址" @ok="handleOk">
<div style="max-height: 600px;overflow-y: auto;padding: 20px" >

  <div v-for="item in a">

    <zhongxuan @itemContent="itemContent" :content="item" />
    <div style="border-bottom: 1px solid #e7e7e7"></div>
  </div>
</div>
  </Modal>


</template>


​

 组件 zhongxuan.vue

<script setup lang="ts">

import {Checkbox} from "ant-design-vue";
import Xuanze from "./xuanze.vue";
import {defineEmits, defineProps, reactive, ref, watch} from "vue";

const props = defineProps(['content'])
const data = ref([])
const value = reactive({
  value: [],
  checkAll: false,
})
const xuan = ref(null)
const indeterminate = ref(false)
const emit = defineEmits(['itemContent']);
const shuju = (obj) => {

  let box = data.value.filter((i) => {
    return i.regionName === obj.regionName
  })
  if (box.length === 0) {
    data.value.push(obj)
  } else {
    data.value.forEach((ite, ind) => {
      if (ite.regionName === obj.regionName) {
        data.value.splice(ind, 1, obj)
      }
    })
  }
  emit('itemContent', {regionName: props.content.regionName, value: obj.value})

}
const zhuangt = (v, val) => {
  if (v == 0) {
    //取消  删除
    value.value.forEach((item, index) => {
      if (item.regionName == val.regionName) {
        value.value.splice(index, 1)
      }
    })

  } else if (v == 1) {
    let ind = null
    let x
    value.value.forEach((item, index) => {
      console.log(item.regionName, val.regionName)
      if (item.regionName == val.regionName) {
        ind = index
      }

    })
    if (ind === null) {
      value.value.push(val)
      ind = value.value.length - 1
    } else {
      value.value.forEach((item, index) => {
        if (item.regionName == val.regionName) {
          console.log(index)
          value.value.splice(index, 1, val)
          ind = index
        }
      })
    }


    // value.value.forEach((item, index) => {
    //   if (item.regionName == val.regionName) {
    //     value.value[index]=val
    //     // value.value.splice(index, 1)
    //   }
    // })

    if (value.value[ind].children.length !== 0 && (value.value[ind].children.length !== val.children.length)) {
      indeterminate.value = true
    }

    // value.value.length>0&&(indeterminate.value = true)
    // indeterminate.value = true
  } else if (v == 2) {
    let x = null
    value.value.forEach((item, index) => {
      if (item.regionName == val.regionName) {
        value.value.splice(index, 1, val)
        x = true
      }
    })

    if (x == null) {
      value.value.push(val)
    }

  }
}
const onCheckAllChange = (e: any) => {
  Object.assign(value, {
    value: e.target.checked ? [...props.content.children] : [],
    indeterminate: false,
  });

  if (e.target.checked) {
    //省全选 控制子全选
    xuan.value.forEach((item, index) => {
      xuan.value[index].xuan()
    })
  } else {
    //省取消 控制子取消
    xuan.value.forEach((item, index) => {
      xuan.value[index].qing()
    })
  }
};

watch(() => value.value, (v) => {

  if (value.value.length === props.content.children.length) {
    // 判断每个的数组是不是一样长 半选或全选
    let num = 0
    value.value.forEach((item, index) => {

      props.content.children.forEach((it, ind) => {
        console.log(item.regionName, props.content.children[ind].regionName)
        if (item.regionName === props.content.children[ind].regionName) {
          if (item.children.length === props.content.children[ind].children.length) {
            num++
          }
        }
      })
    })

    if (num === props.content.children.length) {
      //全选
      indeterminate.value = false
      value.checkAll = true
    } else {
      // 半选
      indeterminate.value = true
      value.checkAll = false
    }

  } else if (value.value.length === 0) {
    indeterminate.value = false
    value.checkAll = false
  } else {
    indeterminate.value = true
    value.checkAll = false
  }
}, {deep: true})

</script>

<template>
  <Checkbox :indeterminate="indeterminate" @change="onCheckAllChange" :checked="value.checkAll">
    {{ content.regionName }}
  </Checkbox>

  <div v-for="it in content.children" style="margin-left: 20px">
   回显数据: {{it.huixian}}
    <Xuanze ref="xuan" @shuju="shuju" @zhuangt="zhuangt" :content="it" :huixian="it.huixian"/>
  </div>
</template>

 组件 xuanze.vue

<script setup lang="ts">
import {ref, defineProps, watch, reactive, onMounted, defineEmits, defineExpose} from "vue";
import {Checkbox, CheckboxGroup} from 'ant-design-vue'

const props = defineProps(['content','huixian'])
const emit = defineEmits(['zhuangt', 'shuju']);
let a = ref(false)
const state = reactive({
  indeterminate: false,
  checkAll: false,
  checkedList: [],
});
onMounted(()=>{
  console.log(props.huixian,props.content)
    if(props.huixian?.length>0){
      props.content.children.forEach(item=>{
        if(props.huixian.includes(item.regionCode)){
          state.checkedList.push(item)
        }
      })
    }
})
const onCheckAllChange = (e: any) => {
  Object.assign(state, {
    checkedList: e.target.checked ? [...props.content.children] : [],
    indeterminate: false,
  });
};
watch(
  () => state.checkedList,
  val => {

    state.indeterminate = !!val.length && val.length < props.content.children.length;
    state.checkAll = val.length === props.content.children?.length;

    if (val.length === props.content.children?.length) {
      emit('zhuangt', 2, props.content)  //全取消  删除
    } else if (val.length && val.length < props.content.children?.length) {
      emit('zhuangt', 1, {regionCode:props.content.regionCode,regionName:props.content.regionName,children:state.checkedList}) //半选 现在选的
    } else {
      emit('zhuangt', 0, props.content) //全选 添加
    }
    //给父级最新选择数据
    emit('shuju', {regionName: props.content.regionName, value: state.checkedList})
  },
  {immediate: true,deep:true}
);
const xuan = () => {
  state.checkAll = true
  state.checkedList = [...props.content.children]
}
const qing = () => {
  state.checkedList.length = 0
  state.checkAll = false
}
defineExpose({
  qing,
  xuan
})
</script>

<template>
选中数据:{{state.checkedList}}
  <div>
    <div style="display: flex">
    <Checkbox :indeterminate="state.indeterminate"
              @change="onCheckAllChange" :checked="state.checkAll">{{ content.regionName }}
    </Checkbox>
    <div @click="a=!a" style="cursor:pointer;color: #0b79ee">展开授权</div>
    </div>
    <CheckboxGroup style="margin-left: 20px" v-if="a" v-model:value="state.checkedList">
      <Checkbox v-for="i in content.children" :value="i">{{ i.regionName }}</Checkbox>
    </CheckboxGroup>
  </div>


</template>

<style scoped lang="less">
/deep/ .ant-checkbox-wrapper+.ant-checkbox-wrapper{
  margin-left: 10px;
}
/deep/ .ant-checkbox-wrapper{
  margin-left: 10px;
}
</style>

 使用  @confirm-event为回调事件 一个参数为收集的数据  回显数据传入curForm_data 格式为

[ { "key": 0, "deliver_areas": "东城区,西城区,朝阳区,丰台区,石景山区,海淀区,门头沟区,武清区,宝坻区,桥西区,高邑县", "trans_weight": 1, "trans_fee": 1, "trans_add_weight": 1, "trans_add_fee": 1, "sele_area_id_array": [ "110101000000", "110102000000", "110105000000", "110106000000", "110107000000", "110108000000", "110109000000", "120114000000", "120115000000", "130104000000", "130127000000" ], "freightExtendId": 50 } ]

<duoxuan @confirm-event="sldHandleConfirmPer" :curForm_data="curForm_data?.data_table"/>

  • 14
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,针对您的问题,我可以提供以下的解决方案: 1. 首先,在 Vue3 工程中安装 ant-design-vue: ```bash npm install ant-design-vue@next ``` 2. 在 main.js 中引入 ant-design-vue 的样式和脚本: ```js import { createApp } from 'vue' import App from './App.vue' import Antd from 'ant-design-vue' import 'ant-design-vue/dist/antd.css' createApp(App).use(Antd).mount('#app') ``` 3. 在组件中使用 a-date-picker 组件,并将选中的日期保存在一个变量中: ```html <template> <a-date-picker v-model:value="selectedDate" style="width: 100%;" /> </template> <script> export default { data() { return { selectedDate: null, // 初始化选中的日期为 null }; }, mounted() { // 获取要回显的日期,假设为 "2022-01-01" const date = new Date("2022-01-01"); // 将选中的日期设置为获取的日期 this.selectedDate = date; }, }; </script> ``` 4. 如果您需要在页面中回显已经选中的日期,可以在组件初始化时将选中的日期传入组件: ```html <template> <a-date-picker v-model:value="selectedDate" style="width: 100%;" /> </template> <script> export default { data() { return { selectedDate: null, // 初始化选中的日期为 null }; }, mounted() { // 获取要回显的日期,假设为 "2022-01-01" const date = new Date("2022-01-01"); // 将选中的日期设置为获取的日期 this.selectedDate = date; }, }; </script> ``` 希望以上解决方案能够帮助到您,如有任何疑问,请随时追问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值