Vue v-select如何置顶常用下拉选项 去重并添加分组分隔符
解决方案
问题原因
之前用concat()拼接两个平级数组的方式,会让相同选项在同一级渲染列表里出现两次,直接触发Vue重复键警告,搜索时也会展示重复选项。v-select本身原生支持分组选项结构,不需要合并数组,就能实现高频选项置顶、保留全量选项原有位置、添加分组标识和分隔线的需求,且逻辑可以直接复用到其他下拉场景。
具体实现
v-select识别标准的分组选项结构,每个分组为包含label(分组名称)和options(分组下选项数组)字段的对象,组件会自动渲染分组标题、组间分隔线,搜索、选中逻辑都能自动适配分组结构,不需要额外开发。
- 替换原有数组拼接逻辑,直接组装成分组格式传给
:options即可,不需要修改全量选项数组的内容、排序,高频选项和全量选项分属不同分组,不会出现平级重复的问题。 - 如果需要自定义分隔线样式、分组标题样式,通过组件提供的
group插槽修改即可。 - 显式给组件添加
value-key="code"配置,指定选项唯一标识字段,彻底避免重复键警告。
修改后完整代码
<template> <div> <v-select v-model="$attrs.countryName" id="country" name="country" autocomplete="off" v-validate="'required'" required class="style-select-filter" @option:selected="$emit('changed', $event)" :options="arrNew" placeholder="Selecione um país" value-key="code" > <!-- 自定义分组分隔线和标题 --> <template #group="{ group }"> <div class="group-divider"></div> <span class="group-label">{{ group.label }}</span> </template> </v-select> <small v-if="errors.has('country')" class="field-text is-danger">{{ errors.first('country') }}</small> </div> </template> <script> let config = { headers: {} } export default { name: "Selectcountry", inject: ['$validator'], data() { return { arrCountry: [], arrMain: [ {"label":"Brasil","code":1}, {"label":"Estados Unidos","code":136} ], arrNew: [] } }, methods: { searchcountries() { this.$http.get('country/list', config).then(response => { this.arrCountry = response.data.pt; // 替换原concat逻辑,组装分组选项 this.arrNew = [ { label: '常用国家', options: this.arrMain }, { label: '全部国家', options: this.arrCountry } ] }).catch(error => { console.log(error) this.errored = true }).finally(() => this.loading = false); } }, mounted() { this.searchcountries(); }, } </script> <style scoped> .group-divider { height: 1px; background: #e5e7eb; margin: 6px 12px; } .group-label { font-size: 12px; color: #6b7280; padding: 0 12px; font-weight: 500; } </style>
复用说明
后续复用到产品、分类等其他下拉场景时,只需要替换两个分组的标题文字、对应高频选项数组、全量选项数组即可,核心逻辑不需要修改。如果要做通用组件,把分组名称、高频选项、全量选项封装成props传入,就能覆盖所有带常用项置顶的下拉选择需求。
内容的提问来源于stack exchange,提问作者GUIJS
相关产品推荐
相关产品推荐

