首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >vue优雅的实现关闭弹框

vue优雅的实现关闭弹框

原创
作者头像
brzhang
修改2020-04-03 16:44:31
2.3K0
修改2020-04-03 16:44:31
举报
文章被收录于专栏:玩转全栈玩转全栈

背景

假如说,有这样一个页面,一个蒙层,然后上面一个弹框,怎么优雅的去做关闭这个弹框呢?

是的,怎么优雅的关闭这个弹框,是今天的主题。

1、点击取消确定按钮,关闭弹框,的的确确,大多数是这样的做法,但是考虑到,用户有可能手指距离这里比较远,所以,操作可能会比较不方便,因此,这种体验似乎并不是很好,所以,慢慢的用户就觉得需要点击蒙层的时候,也能关闭弹框

那么,怎么去实现点击蒙层关闭弹框呢?

1、找到蒙层那个div给蒙层加上 @click='closeDialog',因此,如果你的页面中有很多弹框,那就意味着,你的页面有几个弹框,就要加几个click事件,就问你累不累,在加上取消,确定按钮,想必你肯定开始怀疑人生了。

2、使用全局方式,记得很久之前撸过jquery,jquery里面就一个live绑定事件的功能,大概就是

$(".dialog").live('click',function(){})

以上代码手撸,不保证可用,大概意思就是class为.dialog的element,都绑定一个这样的click事件,不管你当前在不在dom中,后面加进来的也是OK的,想想就觉得挺美好的,那么,可否在Vue中玩一玩呢?

遗憾的是,vue中可没有像jquery种selector的方式,两种框架的本质都不一样,vue中mvvm框架,如果需要用户去像jquery那样找element,本身就显得比较怪怪的,那么怎么办呢?可以这样玩。

document.body.addEventListener('click', event => {
      const className = event.target.className
      const classNameArray = ['tip-operating-layer', 'tip-dialog-wrap']
      if (classNameArray.includes(className)) {
        console.log('关闭浮层')
        this.closeDialog()
      }
 })

我们直接给body绑定了一个click事件,然后event.target.className去比较class,如果是我们弹框的蒙层,就相应这个事件。

所以,你准备在每个页面都加上这一套代码是吗?

我想大多数人肯定是这样想的,难道你没发现,这段代码似乎和业务并没有任何关系,他只是检查是否点击了蒙层而已。因此,这段代码是可以下层的。

问题的关键是,怎么通知到页面去点击到了浮层这样一个事件,并作出相应的处理。

事件总线在这个时候就起到作用了。

事件总线

const install = function(Vue) {
  const eBus = new Vue({
    methods: {
      emit(event, ...args) {
        this.$emit(event, ...args)
      },
      on(event, callback) {
        console.info('...ebus on triggered...')
        this.$on(event, callback)
      },
      off(event, callback) {
        console.info('...ebus off triggered...')
        this.$off(event, callback)
      }
    }
  })
  Vue.prototype.$ebus = eBus
}

export default install

你可能角色事件总线是什么很神秘的黑科技,但是我要告诉你的是,他事件上是一个全局单例而已,无非就是你把数据丢给我,我在把数据丢给这种数据的监听者而已,就比如上面这个插件,直接

Vue.use(ebus)

之后,就相当于Vue的原型链上有了这么一个bus的全局实例,嗯,唯一的。

所以,结合我们上面那个对蒙层点击的判断,就好说了

document.body.addEventListener('click', event => {
  const className = event.target.className
  const classNameArray = ['tip-operating-layer', 'tip-dialog-wrap']
  if (classNameArray.includes(className)) {
    this.$ebus.emit('closepop')
  }
})

直接通过事件总线将这个消息发送给关注这个事件的页面,比如A页面。

created() {
  this.$ebus.on('closepop', this.closeAllDialog)
},
beforeDestroy() {
  this.$ebus.off('closepop')
},

此时具体的业务页面只需要关系我closeAllDialog做什么事情就好了,比如,无脑关闭是所有的弹框:

closeAllDialog() {
  this.isOperationShow = false
  this.isAuthShown = false
  this.isMangerListShow = false
  this.isAddAdminShow = false
  this.isMangerListShow = false
  this.isAddGameShow = false
},

所以,以上骚操作,就做到了,不用在挨个在蒙层上加click事件,就可以关闭弹框了。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 背景
  • 事件总线
相关产品与服务
事件总线
腾讯云事件总线(EventBridge)是一款安全,稳定,高效的云上事件连接器,作为流数据和事件的自动收集、处理、分发管道,通过可视化的配置,实现事件源(例如:Kafka,审计,数据库等)和目标对象(例如:CLS,SCF等)的快速连接,当前 EventBridge 已接入 100+ 云上服务,助力分布式事件驱动架构的快速构建。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档