JeecgBoot自定义多选组件JCheckBtnGroup
使用JDictSelectTag组件过程中,想实现多选标签组件,如下:
官方文档只支持单选,就需要自定义多选组件,官方也有可用的复选框组件JCheckbox组件,不是很喜欢复选框的样式,就自定义一个组件
在JCheckbox基础上修改,将a-ckeckbox-group替换成a-button实现,选择后的逻辑不变,只替换样式,完整代码如下:
<template>
<div class="button-group">
<a-button
v-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 changes
watchEffect(() => {
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 changes
watchEffect(() => {
initOptions();
});
// Initialize options
async 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 event
function handleChange() {
emit('update:value', checkboxArray.value.join(','));
emit('change', checkboxArray.value.join(','));
}
// Toggle checkbox selection
function toggleCheckbox(value) {
if (checkboxArray.value.includes(value)) {
checkboxArray.value = checkboxArray.value.filter(v => v !== value);
} else {
checkboxArray.value.push(value);
}
handleChange();
}
// Get dictionary color
const 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 conditions
const getButtonClass = (value) => {
if (checkboxArray.value.includes(value)) {
return userDictColor.value ? 'button-checked2' : 'button-checked';
}
return '';
};
// Get dynamic button style
const 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,选中后会显示对应的颜色