Необходимо было сделать калькулятор на vue. В данном калькуляторе есть селекты, но так как они уже были стилизованы с помощью jquery styler на всем сайте, то взял готовую верстку от него и на основе этого создал компонент свой с теми же классами. Все работает как нужно, но загвоздка в том что как закрыть селект если он пропал из фокуса или клик прошел вне этого элемента/компонента? Select'ов в калькуляторе может быть несколько.
Ниже приведу код и
ссылку на jsfiddleconst vSelect = {
props: {
name: {
type: String,
required: true
},
label: String,
items: {
required: true
},
value: {
required: true
},
fields: Object,
},
data () {
return {
selectedOption: null,
opened: false
}
},
computed: {
currentValueName() {
if( this.fields ) {
return this.items.find(item => item.id == this.value).name;
} else {
return this.items[value];
}
}
},
created () {
this.selectedOption = this.value;
},
watch: {
value: {
handler(newValue) {
this.selectedOption = newValue;
}
}
},
methods: {
selectItem(index) {
this.$emit('input', index);
this.opened = false;
}
},
template: `
<div class="form-item v-select">
<label :for="name" v-if="label">{{ label }}</label>
<div :class="['jq-selectbox', 'jqselect', {dropdown: opened, opened: opened}]">
<select
:id="name"
:name="name"
class="not-styler"
v-model="selectedOption"
>
<option
v-for="(option, o) in items"
:key="fields ? option[fields.id] : o"
:selected="(fields ? option[fields.id] : o) === value"
:value="fields ? option[fields.id] : o"
>
{{ fields ? option[fields.value] : option }}
</option>
</select>
<div class="jq-selectbox__select" @click="opened = !opened">
<div class="jq-selectbox__select-text">{{ currentValueName }}</div>
<div class="jq-selectbox__trigger">
<div class="jq-selectbox__trigger-arrow"></div>
</div>
</div>
<div class="jq-selectbox__dropdown" v-show="opened">
<ul>
<li
v-for="(option, o) in items"
:key="fields ? option[fields.id] : o"
:class="{selected: (fields ? option[fields.id] : o) === value}"
@click="selectItem(fields ? option[fields.id] : o)"
>
{{ fields ? option[fields.value] : option }}
</li>
</ul>
</div>
</div>
</div>`
};
new Vue({
el: '#preorder',
components: {
'v-select': vSelect,
},
data() {
return {
order: 1,
typeApartment: [
{
id: 1,
name: 'Зал — 210 человек'
},
{
id: 2,
name: 'Зал — 420 человек'
}
],
}
},
});
<div id="preorder">
<v-select
:name="'type-apartment'"
:label="'Тип помещения'"
:items="typeApartment"
:fields="{ id: 'id', value: 'name' }"
v-model="order"
/>
</div>