如何将v-avatar嵌入v-select多选组件的chip子元素中?
解决思路
要实现带前置头像的可关闭多选Select Chips,核心是在selection插槽自定义Chip的同时,正确处理关闭事件并阻止事件冒泡,避免触发Select展开,同时同步更新选中列表。
完整实现代码
<template> <div> <label class="form-label">{{ label }}</label> <v-select v-model="selecteds" item-title="user_name" item-value="id" :items="items" multiple > <template #selection="{ item }"> <v-chip closable :disabled="item.deleted_at" @close="handleChipClose(item, $event)" > <template #prepend> <v-avatar size="32" :image="item.avatar || 'https://i.pravatar.cc/64'" /> </template> {{ item.user_name }} </v-chip> </template> </v-select> <input v-for="selected in selecteds" :key="selected.id" type="hidden" :name="label + '[]'" :value="selected.id" > </div> </template> <script setup> import { ref, watch, defineProps, defineEmits } from 'vue' const props = defineProps({ label: String, items: Array, modelValue: Array }) const emit = defineEmits(['update:modelValue']) const selecteds = ref([...props.modelValue]) const handleChipClose = (item, event) => { // 阻止事件冒泡,避免触发v-select展开 event.stopPropagation() // 从选中列表中移除当前项 const index = selecteds.value.findIndex(i => i.id === item.id) if (index !== -1) { selecteds.value.splice(index, 1) } } // 同步父组件的modelValue状态 watch(selecteds, (newVal) => { emit('update:modelValue', newVal) }) </script>
关键细节说明
- 阻止事件冒泡:在
v-chip的@close事件中调用event.stopPropagation(),避免关闭Chip时触发v-select的点击展开逻辑。 - 手动更新选中列表:自定义
selection插槽时,v-chip的model-value无法直接联动v-select的v-model,所以需要手动从selecteds中移除对应项。 - 正确嵌套头像插槽:把
v-avatar放在v-chip的#prepend插槽内,确保头像嵌入Chip内部,而不是挂在v-select组件上。 - 同步父组件状态:通过
watch监听selecteds变化,触发update:modelValue事件同步给父组件的v-model。
内容的提问来源于stack exchange,提问作者Postizo
相关产品推荐
相关产品推荐

