Полностью свой Select на Vue 3 (composition api)
Надоело мучиться с переназначением стилей и свойств стандартного Select. На Vue 3 проще сделать СВОЙ и придать ЛЮБОЙ вид этому часто используемому элементу.
Источник: Stack Overflow на русском
Надоело мучиться с переназначением стилей и свойств стандартного Select. На Vue 3 проще сделать СВОЙ и придать ЛЮБОЙ вид этому часто используемому элементу.
Доработал для случая нескольких Select
на странице одновременно плюс закрытие при клике в любой области приложения (модифицировал с полезной фичей - отслеживание событий на элементах Root Div по присвоенному имени):
В Главном Компоненте root giv (отслеживаем клик в любой точке):
<div class="flexColSSnw h-100" id="AdminView" @click="noSelectsSet">
<script setup>
//----------- Selects close/open ------------//
const openSelect = ref(null)
provide('openSelect', openSelect)
function noSelectsSet(event) {
if(event.target !== null) {
event.target?.getAttribute('my_select') !== 'select' ? openSelect.value = null : ''
} else {
openSelect.value = null
}
}
В компоненте, где вызываем Select:
<Select :selectType="selectType" :selectSubject="selectSubject" :subjects="subjects" @choseItem="(n) => selectSubject = n></Select>
```
Отдельный модуль Select (переиспользуемый).
Для того чтобы принимать в Root div свой атрибут без emit
- просто ставим его всем элементам селекта:
<template>
<div class="flexRawCCnw" :class="selectSubject ? 'selected' : 'selectPS'" @click="setOpen(selectName)" my_select="select">
<div v-if="!selectSubject" my_select="select">Выбрать "{{selectName}}" </div>
<div v-else my_select="select">{{selectSubject}} </div>
<img src="/img/select.png" alt="up" style="height: 0.75rem; margin-left: auto" my_select="select">
</div>
<div v-if="selectActive === selectName && tactSelect >0" class="optionBlock">
<template v-for="(value, key, index) in subjects">
<template v-if="selectType === 'object'">
<div class="selectGroup">{{ key }}</div>
<template v-for="item in subjects[key]">
<div class="selectOption" @click="send(item, key)">{{ item }}</div>
</template>
</template>
<div v-else class="selectOption" @click="send(value, null)">{{ value }}</div>
</template>
</div>
</template>
<script setup>
import {ref, defineProps, defineEmits, inject, watch} from "vue"
const props = defineProps(['selectName', 'selectType', 'selectSubject', 'subjects'])
const emit = defineEmits(['choseItem'])
const openSelect = inject('openSelect')
function setOpen(selectName) {
openSelect.value === selectName ? openSelect.value = null : openSelect.value = selectName
}
function send (item, key) {
emit('choseItem', [item,key])
}
</script>
<style scoped>
</style>
```