(一)时间选择的下拉菜单;vue实现手写下拉菜单,点击下拉菜单以外的地方,下拉菜单收起;

(1、)利用vue的directives。。。。。。如下:

 <!-- 下拉菜单 -->
<div class="select" v-clickoutside="handleClose">
     <el-button @click="manageUser">{
   
   {choseOpt}}</el-button>
     <ul class="select-box" v-show="selectFlag">
         <li v-for="(item,index) in optList" :key="index" @click="optionClick(item)">
             {
   
   {item.value}}
         </li>
      </ul>
</div>

export default {
    data(){
        return:{
           optList:[{id:1,value:'天猫'},{id:2,value:'专柜'},{id:3,value:'线下'},
                {id:4,value:'网络'},{id:5,value:'roots官方账号'},
                {id:6,value:'其他'}],
           selectFlag:false,
           choseOpt:'',
           selectedID:'',//选中的途径id
        }
    },
//在directives中自定义事件
     directives:{
        clickoutside:{
            bind:function(el,binding,vnode){
                function documentHandler(e){
                    if(el.contains(e.target)){
                        return false;
                    }
                    if(binding.expression){
                        binding.value(e)
                    }
                }
                el._vueClickOutSide_=documentHandler;
                document.addEventListener('click',documentHandler);
            },
            unbind:function(el,binding){
                document.removeEventListener('click',el._vueClickOutSide_)
                delete el._vueClickOutSide_;
            }
        },
        medthods:{
            manageUser(){
                this.selectFlag =! this.selectFlag;

            },
            handleClose(){
                this.selectFlag = false;
            
            },
            optionClick(options){
                console.log(options)
                this.selectFlag = false;
                this.choseOpt = options.value;
                this.selectedID = options.id;
            },
        
        }

}

(2、)利用监听和阻止冒泡的方式

注意:如果不使用@click.stop 就会一直冒泡,“@click.stop”是组织向上冒泡,放在你需要的位置即可

一个时间的选择下拉菜单,点击其他地方下拉菜单收起

//时
<div class="hour-select" @click.stop>
    <input class="time-input"  type="text" id="" v-model="hour" @click="hourOptions">
    <ul class="options-box" v-show="hourFlag">
//:class="{selected:readySelectHour === index}"动态添加class
        <li v-for="(item,index) in hours" :key="index" 
             @click="selectHour(item,index)" 
             :class="{selected:readySelectHour === index}">
             <span>{
   
   {item.name}}</span>
        </li>
     </ul>
</div>
//分
<div class="minute-select" @click.stop>
    <input class="time-input"  type="text" id="" v-model="minute" @click="minuteOptions">
    <ul class="options-box" v-show="minuteFlag">
        <li v-for="(item,index) in minutes" 
            :key="index" @click="selectMin(item,index)" 
            :class="{selected:readySelectMinute === index}">
            <span>{
   
   {item.name}}</span>
        </li>
    </ul> 
</div>

 data() {
     return {
       inputText:'',
       hour: '',
       minute:'',
       domId: '',
       hours: [],
       minutes: [],
       minuteFlag:false,
       hourFlag:false,
       readySelectHour:'',
       readySelectMinute:'',
},
created() {
            let t, m;
            for (let i = 0; i < 24; i++) {
                t = i;
                if (t < 10) {
                    t = '0' + t;
                }
                this.hours.push({id: t, name: t});
            }
            for (let j = 0; j < 60; j++) {
                m = j;
                if (m < 10) {
                    m = '0' + m;
                }
                this.minutes.push({id: m, name: m});
            }
        },
//监听hour和minute的变化,在页面中可以使用 这个watch在控制下拉菜单中没有用到
watch: {
            'hour':function(value) {
                this.hour = value;
            },
            'minute':function(value){
                this.minute = value;
            },
            value(value){
                this.inputText = value;
            },
            id(value) {
                this.domId = value;
            }
        },

 mounted(){
//点击其他地方下拉菜单收起
            window.addEventListener("click", this.eventListener);
        },
methods:{
            hourOptions(){
                this.hourFlag =! this.hourFlag;
                this.minuteFlag =false;
            },
            minuteOptions(){
                this.minuteFlag =! this.minuteFlag;
                this.hourFlag = false;
            },
//选择时间 
            selectHour(itemhour,index){
                this.hour = itemhour.name;
                this.readySelectHour = index;
                this.hourFlag = false;
//inputText此处用于组件间传值
                if(this.minute == ''){
                    this.minute = "00";
                    this.inputText = this.hour.toString() + "00";
                }else{
                    this.inputText = this.hour.toString() + this.minute.toString();
                }
                this.$emit("change", this.inputText)
            },
//选择分钟
            selectMin(itemMin,index){
                this.minute = itemMin.name;
                this.readySelectMinute = index;
                this.minuteFlag = false;
// inputText此处用于组件间传值
                if(this.hour == ''){
                    this.hour = "00";
                    this.inputText = "00" + this.minute.toString();
                }else{
                    this.inputText = this.hour.toString() + this.minute.toString();
                }
                this.$emit("change", this.inputText)
            },
//通用方法 下拉菜单的收起
            eventListener() {
                this.hourFlag = false;
                this.minuteFlag = false;
            },
        },
        destroyed() {
            window.removeEventListener("click", this.eventListener);
        }
<style>
li{
            text-align: center;
            line-height: 32px;
            font-size: 12px;
            &:hover {
                background-color:#f8f9fa;
            }
//动态添加class
            &.selected{
                background-color: #e6fff7;
            }
        }


</style>

猜你喜欢

转载自blog.csdn.net/Sunny_lxm/article/details/95479563