@pilolin
HTML программист

Клик вне области компонента vue?

Необходимо было сделать калькулятор на vue. В данном калькуляторе есть селекты, но так как они уже были стилизованы с помощью jquery styler на всем сайте, то взял готовую верстку от него и на основе этого создал компонент свой с теми же классами. Все работает как нужно, но загвоздка в том что как закрыть селект если он пропал из фокуса или клик прошел вне этого элемента/компонента? Select'ов в калькуляторе может быть несколько.

Ниже приведу код и ссылку на jsfiddle

const 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>
  • Вопрос задан
  • 7837 просмотров
Решения вопроса 2
0xD34F
@0xD34F Куратор тега Vue.js
https://www.npmjs.com/package/v-click-outside

Ну или самостоятельно можете это дело реализовать:

created() {
  const onClickOutside = e => this.opened = this.$el.contains(e.target) && this.opened;
  document.addEventListener('click', onClickOutside);
  this.$on('hook:beforeDestroy', () => document.removeEventListener('click', onClickOutside));
},
Ответ написан
bootd
@bootd
Гугли и ты откроешь врата знаний!
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы