vue实现多选单选
Vue 实现单选功能
使用 v-model 绑定到同一个变量实现单选
通过 radio 类型输入框或自定义样式实现互斥选择
<template>
<div>
<label v-for="option in options" :key="option.value">
<input
type="radio"
v-model="selected"
:value="option.value"
>
{{ option.label }}
</label>
<p>Selected: {{ selected }}</p>
</div>
</template>
<script>
export default {
data() {
return {
selected: '',
options: [
{ value: 'A', label: 'Option A' },
{ value: 'B', label: 'Option B' },
{ value: 'C', label: 'Option C' }
]
}
}
}
</script>
Vue 实现多选功能
使用 v-model 绑定到数组实现多选
通过 checkbox 类型输入框或自定义组件实现多选
<template>
<div>
<label v-for="option in options" :key="option.value">
<input
type="checkbox"
v-model="selected"
:value="option.value"
>
{{ option.label }}
</label>
<p>Selected: {{ selected }}</p>
</div>
</template>
<script>
export default {
data() {
return {
selected: [],
options: [
{ value: 'A', label: 'Option A' },
{ value: 'B', label: 'Option B' },
{ value: 'C', label: 'Option C' }
]
}
}
}
</script>
自定义单选组件实现
创建可复用的单选组件
通过 v-model 实现双向绑定
<template>
<div class="radio-group">
<div
v-for="option in options"
:key="option.value"
class="radio-option"
:class="{ active: modelValue === option.value }"
@click="$emit('update:modelValue', option.value)"
>
{{ option.label }}
</div>
</div>
</template>
<script>
export default {
props: {
options: {
type: Array,
required: true
},
modelValue: {
type: [String, Number],
required: true
}
},
emits: ['update:modelValue']
}
</script>
<style>
.radio-group {
display: flex;
gap: 10px;
}
.radio-option {
padding: 8px 16px;
border: 1px solid #ddd;
cursor: pointer;
}
.radio-option.active {
background-color: #42b983;
color: white;
}
</style>
自定义多选组件实现
创建支持多选的组件
处理数组类型的选中值
<template>
<div class="checkbox-group">
<div
v-for="option in options"
:key="option.value"
class="checkbox-option"
:class="{ active: modelValue.includes(option.value) }"
@click="toggleOption(option.value)"
>
{{ option.label }}
</div>
</div>
</template>
<script>
export default {
props: {
options: {
type: Array,
required: true
},
modelValue: {
type: Array,
required: true
}
},
emits: ['update:modelValue'],
methods: {
toggleOption(value) {
const newValue = [...this.modelValue]
const index = newValue.indexOf(value)
if (index === -1) {
newValue.push(value)
} else {
newValue.splice(index, 1)
}
this.$emit('update:modelValue', newValue)
}
}
}
</script>
<style>
.checkbox-group {
display: flex;
gap: 10px;
}
.checkbox-option {
padding: 8px 16px;
border: 1px solid #ddd;
cursor: pointer;
}
.checkbox-option.active {
background-color: #42b983;
color: white;
}
</style>
使用第三方组件库
Element UI 单选实现
<template>
<el-radio-group v-model="radio">
<el-radio :label="1">Option A</el-radio>
<el-radio :label="2">Option B</el-radio>
</el-radio-group>
</template>
<script>
export default {
data() {
return {
radio: 1
}
}
}
</script>
Element UI 多选实现
<template>
<el-checkbox-group v-model="checkList">
<el-checkbox label="A">Option A</el-checkbox>
<el-checkbox label="B">Option B</el-checkbox>
</el-checkbox-group>
</template>
<script>
export default {
data() {
return {
checkList: []
}
}
}
</script>
性能优化建议
对于大型选项列表使用虚拟滚动
避免在模板中进行复杂计算
使用 key 属性帮助 Vue 高效更新 DOM
<template>
<div style="height: 300px; overflow-y: auto">
<div
v-for="option in visibleOptions"
:key="option.id"
style="height: 30px"
>
<input
type="checkbox"
v-model="selected"
:value="option.id"
>
{{ option.name }}
</div>
</div>
</template>
<script>
export default {
data() {
return {
selected: [],
allOptions: Array.from({ length: 1000 }, (_, i) => ({
id: i,
name: `Option ${i}`
})),
scrollTop: 0
}
},
computed: {
visibleOptions() {
const startIndex = Math.floor(this.scrollTop / 30)
return this.allOptions.slice(startIndex, startIndex + 20)
}
},
mounted() {
this.$el.addEventListener('scroll', (e) => {
this.scrollTop = e.target.scrollTop
})
}
}
</script>






