Пост Как создать простой компонент Vue Custom Select впервые появился на Qvault.

Общеизвестно, что создать собственный тег select с собственным стилем очень сложно. Иногда это невозможно без создания собственного с нуля с использованием комбинации стилизованных div и пользовательского JavaScript. В этой статье вы узнаете, как создать настраиваемый компонент выбора Vue, стиль которого можно легко настроить с помощью собственного CSS. По сути, это тот же компонент, который мы используем в производстве на Qvault, и вы можете увидеть его в действии на игровой площадке.

Демонстрация кодовой песочницы

HTML

<template>
  <div class="custom-select" :tabindex="tabindex" @blur="open = false">
    <div class="selected" :class="{ open: open }" @click="open = !open">
      {{ selected }}
    </div>
    <div class="items" :class="{ selectHide: !open }">
      <div
        v-for="(option, i) of options"
        :key="i"
        @click="
          selected = option;
          open = false;
          $emit('input', option);
        "
      >
        {{ option }}
      </div>
    </div>
  </div>
</template>

Важно отметить следующее:

  • Свойство tabindex позволяет сфокусировать наш компонент, что, в свою очередь, позволяет его размыть. Событие размытия закрывает наш компонент, когда пользователь щелкает за пределами компонента.
  • Выдавая выбранную опцию с помощью параметра «ввод», родительский компонент может реагировать на изменения.

JavaScript

<script>
export default {
  props: {
    options: {
      type: Array,
      required: true,
    },
    default: {
      type: String,
      required: false,
      default: null,
    },
    tabindex: {
      type: Number,
      required: false,
      default: 0,
    },
  },
  data() {
    return {
      selected: this.default
        ? this.default
        : this.options.length > 0
        ? this.options[0]
        : null,
      open: false,
    };
  },
  mounted() {
    this.$emit("input", this.selected);
  },
};
</script>

Важное замечание о JavaScript:

  • Мы также передаем выбранное значение в mount, чтобы родителю не нужно было явно устанавливать значение по умолчанию.
  • Если наш выбранный компонент является небольшой частью более крупной формы, то мы хотим иметь возможность установить правильный tabindex.

CSS

<style scoped>

.custom-select {
  position: relative;
  width: 100%;
  text-align: left;
  outline: none;
  height: 47px;
  line-height: 47px;
}

.custom-select .selected {
  background-color: #0a0a0a;
  border-radius: 6px;
  border: 1px solid #666666;
  color: #fff;
  padding-left: 1em;
  cursor: pointer;
  user-select: none;
}

.custom-select .selected.open {
  border: 1px solid #ad8225;
  border-radius: 6px 6px 0px 0px;
}

.custom-select .selected:after {
  position: absolute;
  content: "";
  top: 22px;
  right: 1em;
  width: 0;
  height: 0;
  border: 5px solid transparent;
  border-color: #fff transparent transparent transparent;
}

.custom-select .items {
  color: #fff;
  border-radius: 0px 0px 6px 6px;
  overflow: hidden;
  border-right: 1px solid #ad8225;
  border-left: 1px solid #ad8225;
  border-bottom: 1px solid #ad8225;
  position: absolute;
  background-color: #0a0a0a;
  left: 0;
  right: 0;
  z-index: 1;
}

.custom-select .items div {
  color: #fff;
  padding-left: 1em;
  cursor: pointer;
  user-select: none;
}

.custom-select .items div:hover {
  background-color: #ad8225;
}

.selectHide {
  display: none;
}
</style>

Этот CSS — просто пример, это то, что мы используем в приложении Qvault. Не стесняйтесь изменять стиль в соответствии с вашими потребностями.

Если вы поместите три раздела вместе в один и тот же файл, у вас останется хорошо инкапсулированный пользовательский компонент выбора одного файла! Опять же, проверьте d e mo для живого примера.

Спасибо за чтение!

Подпишитесь на нас в Твиттере @q_vault, если у вас есть какие-либо вопросы или комментарии

Пройдите несколько курсов кодирования на нашей новой платформе

Подпишитесь на нашу рассылку, чтобы получать больше статей по программированию

Статьи по Теме