CustomCheckboxForm.vue 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. <template>
  2. <div class="custom_check_box">
  3. <div class="search_tab_head" v-if="props.showOperation && !props.disabled">
  4. <span class="check_btn">
  5. <span @click="HandleCheckAllOrNot">
  6. <input :checked="checkedList.length == props.selectList.length && props.selectList.length !== 0 " type="checkbox" @change="HandleCheckChange($event)">全选
  7. </span>
  8. <span>
  9. 已选择
  10. <span style="color: #2E64FA;">{{ checkedList.length }}</span>人
  11. </span>
  12. </span>
  13. <FormSearchGroup
  14. @searchChange="(params)=>HandleSearchChange(params)"
  15. :searchList="[{
  16. key:'peopleName',
  17. type:'input',
  18. placeholder:'请输入关键词搜索'
  19. }]"/>
  20. </div>
  21. <div class="data_area">
  22. <slot></slot>
  23. <div class="search_content" style="">
  24. <span
  25. v-for="item in props.selectList"
  26. :key="item.value"
  27. @click="props.disabled ? '' : HandleCheckOrUncheck(item.value)"
  28. :class="{active:checkedList.includes(item.value) || props.disabled }"
  29. >{{ item.label }}</span>
  30. </div>
  31. </div>
  32. </div>
  33. </template>
  34. <script setup lang="ts">
  35. import {ref, watch} from 'vue'
  36. import FormSearchGroup from './FormSearchGroup.vue';
  37. interface SelectItem {
  38. label:String,
  39. value:String
  40. }
  41. const props = defineProps({
  42. selectList:{
  43. required:true,
  44. type:Array<SelectItem>
  45. },
  46. disabled:{
  47. required:false,
  48. type:Boolean
  49. },
  50. defaultCheckedList:{
  51. required:false,
  52. type:Array<SelectItem>
  53. },
  54. showOperation:{
  55. type:Boolean,
  56. default:true
  57. }
  58. })
  59. const emit = defineEmits(['boxSearchChange','formItemChange'])
  60. const checkedList = ref([])
  61. const HandleCheckOrUncheck = (item)=>{
  62. console.log('当前点击的元素',item)
  63. if(checkedList.value.includes(item)){
  64. checkedList.value = checkedList.value.filter(checkItm=>checkItm !== item)
  65. }else{
  66. checkedList.value.push(item)
  67. }
  68. console.log('最终过滤后的值',checkedList.value)
  69. // 最终的结果值 通知 父组件
  70. emit('formItemChange',checkedList.value)
  71. }
  72. const HandleCheckAllOrNot = ()=>{
  73. if(checkedList.value.length == props.selectList.length){
  74. checkedList.value = []
  75. }else if(checkedList.value.length < props.selectList.length){
  76. checkedList.value = props.selectList.map(item=>item.value)
  77. }
  78. // 最终的结果值 通知 父组件
  79. emit('formItemChange',checkedList.value)
  80. }
  81. const HandleSearchChange = (params)=>{
  82. console.log('searchParams',params)
  83. // 要变更搜索列表,传到父组件去变更
  84. emit('boxSearchChange',params)
  85. }
  86. const HandleCheckChange = (e)=>{
  87. console.log('选中的值:',e.target.value)
  88. }
  89. watch(()=>props.selectList,(newVal)=>{
  90. console.log('盒子列表变化了',newVal)
  91. checkedList.value = []
  92. })
  93. watch(()=>props.defaultCheckedList,(newVal)=>{
  94. // console.log('获取到默认参数了',newVal)
  95. if(newVal){
  96. checkedList.value = newVal
  97. emit('formItemChange',newVal)
  98. }
  99. },{immediate:true})
  100. </script>
  101. <style lang="scss" scoped>
  102. .custom_check_box{
  103. width: 100%;
  104. display: flex;
  105. flex-direction: column;
  106. gap:10px;
  107. line-height: 1.5 !important;
  108. .search_tab_head{
  109. display: flex;
  110. justify-content: space-between;
  111. align-items: center;
  112. .check_btn{
  113. display: flex;
  114. align-items: center;
  115. gap:20px;
  116. >span{
  117. display: flex;
  118. align-items: center;
  119. &:nth-child(1){
  120. gap:8px;
  121. }
  122. }
  123. }
  124. }
  125. .data_area{
  126. display: flex;
  127. flex-direction: row;
  128. justify-content: flex-start;
  129. gap: 10px;
  130. }
  131. .search_content{
  132. width: 100%;
  133. border:dashed #E4E7ED 1px;
  134. border-radius: 6px;
  135. padding:10px;
  136. display: flex;
  137. flex-wrap: wrap;
  138. align-content: flex-start;
  139. gap:10px;
  140. min-height:50px;
  141. max-height: calc(32px * 3 + 2 * 10px + 20px );
  142. overflow: auto;
  143. >span{
  144. border:solid #DCDFE6 1px;
  145. padding: 6px 18px;
  146. height: 32px;
  147. display: flex;
  148. justify-content: center;
  149. align-items: center;
  150. border-radius: 4px;
  151. &.active{
  152. border-color: #2E64FA;
  153. color:#2E64FA;
  154. }
  155. &:hover{
  156. cursor: pointer;
  157. }
  158. }
  159. }
  160. }
  161. </style>