hc-form-checkbox-group.vue 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. <template>
  2. <div
  3. :class="isFocus ? 'is-focus' : ''" class="hc-form-checkbox-group-box"
  4. @keydown.shift.up="keyupShiftUp"
  5. @keydown.shift.down="keyupShiftDown"
  6. @keydown.shift.left="keyupShiftLeft"
  7. @keydown.shift.right="keyupShiftRight"
  8. >
  9. <ElCheckbox
  10. v-for="item in checkboxDatas" :key="item.key" :checked="item.checked"
  11. @change="onCheckboxChange($event, item)"
  12. >
  13. {{ item.name }}
  14. </ElCheckbox>
  15. <input :id="keyname" class="hc-checkbox-group-input" @blur="handleBlur" @focus="handleFocus">
  16. </div>
  17. </template>
  18. <script>
  19. export default {
  20. inheritAttrs: false,
  21. }
  22. </script>
  23. <script setup>
  24. import { nextTick, ref, watch } from 'vue'
  25. import { ElCheckbox } from 'element-plus'
  26. import { arrIndex, deepClone, isNullES } from 'js-fast-way'
  27. const props = defineProps({
  28. ui: {
  29. type: String,
  30. default: '',
  31. },
  32. datas: {
  33. type: Array,
  34. default: () => ([]),
  35. },
  36. objs: {
  37. type: Array,
  38. default: () => ([]),
  39. },
  40. val: {
  41. type: [String, Number],
  42. default: '',
  43. },
  44. keyname: {
  45. type: [String, Number],
  46. default: '',
  47. },
  48. })
  49. //事件
  50. const emit = defineEmits(['change', 'keydowns'])
  51. //变量
  52. const checkboxDatas = ref([])
  53. //渲染完成
  54. nextTick(() => {
  55. setInitDatas(deepClone(props.datas), deepClone(props.objs))
  56. })
  57. //监听表头
  58. watch(() => [
  59. props.val,
  60. ], ([val]) => {
  61. setModelVal(val)
  62. })
  63. //处理初始数据
  64. const setInitDatas = (datas, objs) => {
  65. for (let i = 0; i < datas.length; i++) {
  66. objs.push({ key: String(datas[i]), name: datas[i] })
  67. }
  68. checkboxDatas.value = objs
  69. setModelVal(props.val)
  70. }
  71. //处理数据
  72. const setModelVal = (val) => {
  73. const datas = deepClone(checkboxDatas.value)
  74. if (!isNullES(val)) {
  75. const arr = String(val).split(',')
  76. for (let i = 0; i < arr.length; i++) {
  77. const item = String(arr[i])
  78. const index = arrIndex(datas, 'key', item)
  79. datas[index].checked = true
  80. }
  81. }
  82. checkboxDatas.value = datas
  83. }
  84. //当绑定值变化时触发的事件
  85. const onCheckboxChange = (val, item) => {
  86. item.checked = val
  87. getCheckedValue()
  88. }
  89. //取选中的值
  90. const getCheckedValue = () => {
  91. let valString = ''
  92. const datas = checkboxDatas.value
  93. for (let i = 0; i < datas.length; i++) {
  94. if (datas[i].checked) {
  95. const key = String(datas[i].key)
  96. valString = valString ? `${valString},${key}` : key
  97. }
  98. }
  99. //事件返回
  100. emit('change', {
  101. key: props.keyname,
  102. val: valString,
  103. })
  104. }
  105. //向上
  106. const keyupShiftUp = (e) => {
  107. emit('keydowns', { type: 'up', name: { target: { id: props.keyname } }, key: props.keyname, e })
  108. }
  109. //向下
  110. const keyupShiftDown = (e) => {
  111. emit('keydowns', { type: 'down', name: { target: { id: props.keyname } }, key: props.keyname, e })
  112. }
  113. //向左
  114. const keyupShiftLeft = (e) => {
  115. emit('keydowns', { type: 'left', name: { target: { id: props.keyname } }, key: props.keyname, e })
  116. }
  117. //向右
  118. const keyupShiftRight = (e) => {
  119. emit('keydowns', { type: 'right', name: { target: { id: props.keyname } }, key: props.keyname, e })
  120. }
  121. //获得焦点
  122. const isFocus = ref(false)
  123. const handleFocus = () => {
  124. isFocus.value = true
  125. }
  126. //失去焦点
  127. const handleBlur = () => {
  128. isFocus.value = false
  129. }
  130. </script>
  131. <style lang="scss" scoped>
  132. .hc-form-checkbox-group-box {
  133. position: relative;
  134. width: 100%;
  135. height: initial;
  136. border-radius: 4px;
  137. transition: box-shadow 0.3s, background-color 0.3s;
  138. &.is-focus, &:hover {
  139. background-color: #eddac4;
  140. box-shadow: 0 0 0 1.5px var(--el-color-primary) inset;
  141. }
  142. .hc-checkbox-group-input {
  143. position: absolute;
  144. z-index: -1;
  145. right: 10px;
  146. width: 10px;
  147. }
  148. }
  149. </style>