<CheckListWithIcon v-model="checkList" :options="industryOptions" />
const checkList = ref([]);
const industryOptions = ref([
{ value: '0', label: '带发货' },
{ value: '1', label: '运输中' },
{ value: '2', label: '已到货' }
]);
<template>
<div class="checklist-with-icon">
<el-checkbox-group v-model="innerValue" class="checkbox-group">
<div v-for="option in options" :key="option.value" class="checkbox-item" @click="toggleOption(option.value)">
<component :is="loadImageAsset(
innerValue.includes(option.value)
? 'multipleselectio.png'
: 'multiplechoice.png'
)" class="icon" />
<span class="custom-label">{{ option.label }}</span>
</div>
</el-checkbox-group>
</div>
</template>
<script setup>
import { ref, watch } from 'vue'
import { loadImageAsset } from '@/utils/loadImageAsset.js'
const props = defineProps({
modelValue: {
type: Array,
default: () => []
},
options: {
type: Array,
default: () => []
}
})
const emit = defineEmits(['update:modelValue'])
// 内部值,用于双向绑定
const innerValue = ref(Array.isArray(props.modelValue) ? [...props.modelValue] : [])
// 监听内部值变化,同步到父组件
watch(innerValue, (newVal) => {
emit('update:modelValue', newVal)
}, { deep: true }) // 数组内部变化也能监听到
// 监听外部值变化
watch(() => props.modelValue, (newVal) => {
if (Array.isArray(newVal)) {
innerValue.value = [...newVal]
}
}, { deep: true })
// 切换选项的选中状态(核心方法)
const toggleOption = (value) => {
const index = innerValue.value.indexOf(value)
if (index > -1) {
// 已选中,移除
innerValue.value = innerValue.value.filter(item => item !== value)
} else {
// 未选中,添加
innerValue.value = [...innerValue.value, value]
}
}
</script>
<style scoped>
.checklist-with-icon {
display: flex;
align-items: center;
gap: 16px;
flex-wrap: nowrap;
/* 防止换行 */
}
.checkbox-item {
display: flex;
align-items: center;
gap: 8px;
cursor: pointer;
user-select: none;
/* 防止文字被选中 */
}
.icon {
width: 40px;
height: 40px;
flex-shrink: 0;
}
/* 自定义标签样式,替代原生复选框标签 */
.custom-label {
margin: 20px 30px;
padding: 0;
line-height: 1;
font-size: 40px;
cursor: pointer;
font-weight: 400;
color: #656C83;
line-height: 21px;
text-align: left;
font-style: normal;
text-transform: none;
/* margin-left: 20px; */
}
.checkbox-group {
display: flex;
}
</style>
<style>
.el-checkbox__input {
cursor: pointer;
display: inline-flex;
outline: none;
position: relative;
display: none;
white-space: nowrap;
}
</style>