一个简单的效果,点击导航栏弹出菜单后,在菜单外点击触发失焦,自动关闭菜单
本文采用Vant组件
核心:通过触发菜单内的input
聚焦失焦控制显示/隐藏
导航栏:
<van-nav-bar title="导航栏" left-arrow @click="handleRight"> <van-icon name="ellipsis" v-slot:right /></van-nav-bar>
菜单:
<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>
.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; }}
事件:
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() } }) } }}
问题:
菜单栏点击事件
handleMenu
与输入框失焦menuBlur
冲突由于js是单线程,所以两者无法同时进行,加个延迟
menuBlur(){ setTimeout(() => { this.isShowMenu = false; }, 100)}
输入框聚焦同时弹出键盘
如果把input类型设置为hidden反而不能聚焦,所以加个只读属性readonly
<input ref="MenuInput" readonly type="text" @blur="menuBlur" />
其他组件同时出发失焦事件
在用ElementUI的日期选择器时,其自带的@blur
会上浮,不知道算不算bug。
此处带上事件修饰符可解决<el-date-picker @blur.native.capture="pickerBlur"></el-date-picker>