결과 화면

 

1. BaseSelect 컴포넌트 만들기

  • components/base/BaseSelect.vue
  1. form-select와 form-select-list로 나누어 html을 작성한다. 이때 form-select-list 부분은 리스트의 길이가 3개가 넘어갈 경우, 스크롤이 나타날 수 있게끔 class 속성을 추가한다.
  2. isOpen Boolean 속성을 이용해 form-select 영역을 클릭했을 때 form-select-list가 나타날 수 있도록 v-if와 @click 이벤트를 추가한다.
  3. props로 전달받을 데이터의 타입을 정의한다.
  4. computed와 methods를 이용해 form-select-list를 클릭했을 때 그 값이 form-select에 노출될 수 있도록 만든다.
  5. 공통으로 적용할 css/scss를 작성한다.
<template>
  <div
    class="base-select"
    :class="[
      shape,
      { 'open': isOpen }
    ]">

    <div
      class="form-select"
      @click="isOpen = !isOpen">
      <p :class="[{ 'selected': isSelect }]">{{ selected }}</p>
      <svg width="12" height="8" viewBox="0 0 12 8" fill="none" xmlns="http://www.w3.org/2000/svg">
        <path d="M11 1.17C10.8126 0.983753 10.5592 0.879211 10.295 0.879211C10.0308 0.879211 9.77737 0.983753 9.59001 1.17L6.00001 4.71L2.46001 1.17C2.27265 0.983753 2.0192 0.879211 1.75501 0.879211C1.49082 0.879211 1.23737 0.983753 1.05001 1.17C0.956281 1.26297 0.881887 1.37357 0.831118 1.49543C0.780349 1.61729 0.754211 1.74799 0.754211 1.88C0.754211 2.01202 0.780349 2.14272 0.831118 2.26458C0.881887 2.38644 0.956281 2.49704 1.05001 2.59L5.29001 6.83C5.38297 6.92373 5.49357 6.99813 5.61543 7.04889C5.73729 7.09966 5.868 7.1258 6.00001 7.1258C6.13202 7.1258 6.26273 7.09966 6.38459 7.04889C6.50645 6.99813 6.61705 6.92373 6.71001 6.83L11 2.59C11.0937 2.49704 11.1681 2.38644 11.2189 2.26458C11.2697 2.14272 11.2958 2.01202 11.2958 1.88C11.2958 1.74799 11.2697 1.61729 11.2189 1.49543C11.1681 1.37357 11.0937 1.26297 11 1.17Z" fill="#111111"/>
      </svg>
    </div>

    <div
      v-if="isOpen"
      class="form-select-list">
      <div :class="{ 'scroll': options.length > 3 }">
        <ul>
          <li
            v-for="(option, key) in options"
            :key="`option-${key}`"
            @click="selectOption(option)">
            {{ option.name }}
          </li>
        </ul>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: 'BaseSelect',

  props: {
    shape: {
      type: String
    },
    isSelect: {
      type: Boolean,
      default: false
    },
    options: {
      type: Array
    },
    defaultValue: {
      type: String
    }
  },

  data() {
    return {
      isOpen: false
    }
  },

  computed: {
    selected: {
      get() {
        return this.options.find(item => item.name === this.defaultValue)?.name || this.defaultValue || '옵션을 선택해 주세요.'
      }
    }
  },

  methods: {
    selectOption(option) {
      this.selected = option.name
      this.isOpen = false
      this.isSelect = true
      this.$emit('input', option.name)
    }
  }
}
</script>

<style lang="scss" scoped>
.base-select {
  position: relative;
  
  .form-select {
    display: flex;
    justify-content: space-between;
    align-items: center;
    width: 100%;
    height: 60px;
    padding: 0 15px;
    background-color: #fff;
    border: 1px solid #ddd;
    cursor: pointer;

    svg {
      transition: all 0.3s;
    }
  }

  .form-select-list {
    position: absolute;
    top: 65px;
    left: 0;
    right: 0;
    z-index: 10;

    & > div {
      &.scroll {
        height: 240px;

        ul {
          overflow-y: auto;
          height: 100%;
          padding-right: 5px;

          &::-webkit-scrollbar {
            width: 5px;
          }

          &::-webkit-scrollbar-thumb {
            background-color: #f5f5f5;
          }
        }
      }
    }

    ul {
      background-color: #fff;
      border: 1px solid #333;

      li {
        height: 60px;
        padding: 0 15px;
        line-height: 60px;
        transition: all .3s;
        cursor: pointer;

        &:hover {
          background-color: #f5f5f5;
        }
      }
    }
  }
  ...
}
</style>

 

2. 페이지에 BaseSelect 컴포넌트 import 하기

  • pages/index.vue
  1. 만든 <BaseSelect> 컴포넌트를 import 한다.
  2. data() 부분에 props로 넘길 데이터를 작성한다. selectValue1, selectValue2는 빈 값으로 만들어 클릭한 값이 들어올 수 있도록 한다. 
  3. v-model을 통해서 selectValue 값이 바뀌는 것을 확인한다.
<template>
  <TheLayout>
    <div class="select">
      <BaseSelect
        :options="selectList"
        :defaultValue="selectValue1"
        v-model="selectValue1"/>

      <BaseSelect
        shape="black"
        :options="selectList"
        :defaultValue="selectValue2"
        v-model="selectValue2"/>
    </div>
  </TheLayout>
</template>

<script>
import TheLayout from '@/components/layout/TheLayout'
import BaseSelect from '@/components/base/BaseSelect'

export default {
  name: 'Main',

  components: {
    TheLayout,
    BaseSelect
  },

  data() {
    return {
      selectValue1: '',
      selectValue2: '',

      selectList: [
        {
          name: '1번'
        },
        {
          name: '2번'
        },
        {
          name: '3번'
        },
        {
          name: '4번'
        },
        {
          name: '5번'
        }
      ]
    }
  }
}
</script>

<style lang="scss" scoped>
...
</style>

+ Recent posts