小聂子客栈

自定义导航栏菜单失焦

热度

一个简单的效果,点击导航栏弹出菜单后,在菜单外点击触发失焦,自动关闭菜单

本文采用Vant组件
核心:通过触发菜单内的input聚焦失焦控制显示/隐藏

导航栏:

1
2
3
<van-nav-bar title="导航栏" left-arrow @click="handleRight">
<van-icon name="ellipsis" v-slot:right />
</van-nav-bar>

菜单:

1
2
3
4
5
6
7
8
<div v-show="isShowMenu" class="nav-menu">
<ul>
<li v-for="item in menuList"
:key="item"
@click="handleMenu(item)">{{ item }}</li>
</ul>
<input ref="MenuInput" type="text" @blur="menuBlur" />
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
.nav-menu{
position: fixed;
top: 40px;
right: 5px;
input{
position: absolute;
left: 0;
bottom: 0;
width: 0;
height: 0;
margin: 0;
border: none;
outline: 0;
opacity: 0;
-webkit-appearence: none;
}
}

事件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
export default{
name: 'custom-nav',
data(){
return {
isShowMenu: false,// 控制菜单
menuList: ['操作1', '操作2'],// 菜单
}
},
methods: {
handleMenu(item){// 点击菜单项
console.log(item)
},
menuBlur(){// 输入框失焦 =》 隐藏菜单
this.isShowMenu = false
},
handleRight(){// 点击导航栏右侧
this.isShowMenu = !this.isShowMenu
// trigger焦点
this.$nextTick(() => {
if(this.$refs.MenuInput){
this.$refs.MenuInput.focus()
}else{
this.$refs.MenuInput.blur()
}
})
}
}
}

问题:

  1. 菜单栏点击事件handleMenu与输入框失焦menuBlur冲突
    由于js是单线程,所以两者无法同时进行,加个延迟

    1
    2
    3
    4
    5
    menuBlur(){
    setTimeout(() => {
    this.isShowMenu = false;
    }, 100)
    }
  2. 输入框聚焦同时弹出键盘
    如果把input类型设置为hidden反而不能聚焦,所以加个只读属性readonly

    1
    <input ref="MenuInput" readonly type="text" @blur="menuBlur" />
  3. 其他组件同时出发失焦事件
    在用ElementUI的日期选择器时,其自带的@blur会上浮,不知道算不算bug。
    此处带上事件修饰符可解决

    1
    <el-date-picker @blur.native.capture="pickerBlur"></el-date-picker>

扫描二维码,分享此文章