vue优雅的实现关闭弹框

2020-04-03 16:44:31 浏览数 (1)

背景

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

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

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

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

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

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

代码语言:javascript复制
$(".dialog").live('click',function(){})

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

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

代码语言:javascript复制
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,如果是我们弹框的蒙层,就相应这个事件。

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

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

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

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

事件总线

代码语言:javascript复制
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

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

代码语言:javascript复制
Vue.use(ebus)

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

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

代码语言:javascript复制
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页面。

代码语言:javascript复制
created() {
  this.$ebus.on('closepop', this.closeAllDialog)
},
beforeDestroy() {
  this.$ebus.off('closepop')
},

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

代码语言:javascript复制
closeAllDialog() {
  this.isOperationShow = false
  this.isAuthShown = false
  this.isMangerListShow = false
  this.isAddAdminShow = false
  this.isMangerListShow = false
  this.isAddGameShow = false
},

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

0 人点赞