JeecgBoot自定义多选组件JCheckBtnGroup
使用JDictSelectTag组件过程中,想实现多选标签组件,如下:
官方文档只支持单选,就需要自定义多选组件,官方也有可用的复选框组件JCheckbox组件,不是很喜欢复选框的样式,就自定义一个组件
在JCheckbox基础上修改,将a-ckeckbox-group替换成a-button实现,选择后的逻辑不变,只替换样式,完整代码如下:
<template><div class="button-group"><a-buttonv-for="option in checkOptions":key="option.value":class="getButtonClass(option.value)":style="getButtonStyle(option.value)"@click="toggleCheckbox(option.value)">{{ option.label }}</a-button></div>
</template><script lang="ts">import { defineComponent, ref, watchEffect, onMounted } from 'vue';import { propTypes } from '/@/utils/propTypes';import { useAttrs } from '/@/hooks/core/useAttrs';import { initDictOptions } from '/@/utils/dict/index';import { useRootSetting } from '@/hooks/setting/useRootSetting';export default defineComponent({name: 'JCheckBtnGroup',props: {value: propTypes.oneOfType([propTypes.string, propTypes.number]),dictCode: propTypes.string,useDicColor: propTypes.bool.def(false),options: {type: Array,default: () => [],},},emits: ['change', 'update:value'],setup(props, { emit }) {const attrs = useAttrs();const checkOptions = ref<any[]>([]);const checkboxArray = ref<any[]>([]);const bgColor = ref('');const userDictColor = ref(false);onMounted(() => {const { getThemeColor } = useRootSetting();userDictColor.value = props.useDicColor;bgColor.value = getThemeColor.value;document.documentElement.style.setProperty('--bg-color', getThemeColor.value);});// Watch for value changeswatchEffect(() => {let temp = props.value;if (!temp && temp !== 0) {checkboxArray.value = [];} else {temp = temp + '';checkboxArray.value = temp.split(',');}if (props.value === '' || props.value === undefined) {checkboxArray.value = [];}});// Watch for dictCode changeswatchEffect(() => {initOptions();});// Initialize optionsasync function initOptions() {if (props.options && props.options.length > 0) {checkOptions.value = props.options;return;}if (props.dictCode) {const dictData = await initDictOptions(props.dictCode);checkOptions.value = dictData.reduce((prev, next) => {if (next) {const value = next['value'];prev.push({label: next['text'],value: value,color: next['color'],});}return prev;}, []);}}// Handle change eventfunction handleChange() {emit('update:value', checkboxArray.value.join(','));emit('change', checkboxArray.value.join(','));}// Toggle checkbox selectionfunction toggleCheckbox(value) {if (checkboxArray.value.includes(value)) {checkboxArray.value = checkboxArray.value.filter(v => v !== value);} else {checkboxArray.value.push(value);}handleChange();}// Get dictionary colorconst getDicColor = (value) => {if (props.useDicColor) {const findItem = checkOptions.value.find((item) => item.value == value);if (findItem) {return findItem.color;}}return null;};// Get button class based on conditionsconst getButtonClass = (value) => {if (checkboxArray.value.includes(value)) {return userDictColor.value ? 'button-checked2' : 'button-checked';}return '';};// Get dynamic button styleconst getButtonStyle = (value) => {if (checkboxArray.value.includes(value)) {return {color: '#fff',backgroundColor: userDictColor.value ? getDicColor(value) : bgColor.value,borderColor: bgColor};}return {color: '#000',backgroundColor: '#fff',};};return { checkboxArray, checkOptions, attrs, handleChange, getDicColor, toggleCheckbox, getButtonStyle, userDictColor, getButtonClass, bgColor };},});
</script><style lang="less" scoped>.button-group {display: flex;flex-wrap: wrap;gap: 8px;}.a-button {margin: 4px;border-radius: 8px;font-size: 14px;border: 1px solid transparent;}/*.button-checked {border-color: var(--bg-color);}.button-checked2 {border-color: var(--bg-color);}*/
</style>
字典中配置颜色,并在componrntProps中设置useDicColor: true,选中后会显示对应的颜色