下拉选择器组件

展示

在这里插入图片描述
当鼠标放置下拉选择器自动弹出

代码

<template>
  <div class="divInput" @mouseover="hover = true" @mouseleave="hover = false">
    <div class="input" :class="{'hover': hover}" @click="openValue" >
      <div v-if="!props.slotTitle">
        <span>{{ value }}</span>
        <el-icon><ArrowDown /></el-icon>
      </div>
      <slot name="title"></slot>
    </div>
    <div class="list" v-show="hover">
      <ul v-if="props.options" :style="{width: listWidth}">
        <li
          @click="getvalue(item)" 
          v-for="item in props.options" 
          :value="item.value"
          :key="item.label"
        >{{ item.label }}</li>
      </ul>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, Ref } from 'vue'

interface option {
  value: string,
  label: string
}

let show:Ref<boolean> = ref(false)
let hover:Ref<boolean> = ref(false)
let value:Ref<string> = ref('')

function openValue(){
  show.value = !show.value
}

function getvalue(item) {
  emit('change', item)
  show.value = false
  if(props.slotTitle) return
  if(props.title) return
  value.value = item.label
}

const props = defineProps({
  options: {
    type: Array<option>,
    default: []
  },
  title: {
    type: String,
    default: ''
  },
  defaultValue: {
    type: String,
    default: ''
  },
  listWidth: {
    type: String,
    default: 'auto'
  },
  slotTitle: {
    type: Boolean,
    default: false
  }
})

const emit = defineEmits<{
  (e: 'change', val: option): void
}>()

onMounted(()=>{
  if(props.defaultValue) value.value = props.defaultValue
  else if(props.title) value.value = props.title
  else value.value = props.options[0]?.label
})

</script>

<style lang="scss" scoped>
.divInput{
  height: 100%;
}
  ul li{
    list-style: none;
    border: none;
  }
  .hover {
    @include bg_color('bg-color');
  }
  .input{
    position: relative;
    height: 35px;
    line-height: 35px;
    padding: 2.5px 6px;
    @include color('font-light-color');
  }
  .list{
    position: relative;
    z-index: 10000;
    @include bg_color('bg-color');
    ul {
      position: absolute;
      top: 0;
      left: 0;
      margin: 0;
      padding: 0;
      max-height: 270px;
      overflow-y: auto;
      overflow-x: hidden;
      @include bg_color('bg-color');
      @include color('font-light-color2');
    }
    li {
      width: 100%;
      height: 29px;
      cursor: pointer;
      line-height: 29px;
      margin: 0;
      padding: 0;
      padding-left: 8px;
      &:hover{
        @include bg_color('select-color');
      }
    }
  }
</style>

属性

属性名描述
options下拉列表(option数组)
title选择器占位符(不会根据用户选择而改变),没有title的时候,默认为下拉列表第一个值,且会根据用户选择改变
defaultValue设置初始值
listWidth设置下拉列表的宽度
slotTitle是否使用自定义下拉选择器占位符

ps:option定义为抽象对象,如下代码

interface option {
  value: string,
  label: string
}

方法

方法名描述
change当用户点击选择时触发(item:返回option实例)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值