Vue 实现点击空白处隐藏某节点的三种方式(指令、普通、遮罩)

在项目中往往会有这样的需求: 弹出框(或Popover)在 show 后,点击空白处可以将其 hide。

针对此需求,整理了三种实现方式,大家按实际情况选择。

当然,我们做项目肯定会用到 UI 框架,常见的 Element 中的组件提供了这样的方法。

但是,就算使用框架,有些时候还是要用到的,比如:

Element 中的 Popover,当我们想使用手动方式(trigger 触发方式为 manual时)控制它的 show & hide 的时候,就要自己实现这个功能啦。

第一种方式:最普通的手动监听判断

<span ref="projectButton">
  <el-popover v-model="visible" trigger="manual" placement="bottom" @show="show" @hide="hide">
   <p>啦啦啦</p>
   <el-button slot="reference" type="primary" @click="visible = !visible">show</el-button>
  </el-popover>
</span>
data () {
 return {
  visible: false
 }
},
methods: {
 show () {
  document.addEventListener('click', this.hidePanel, false)
 },
 hide () {
  document.removeEventListener('click', this.hidePanel, false)
 },
 hidePanel (e) {
  if (!this.$refs.projectButton.contains(e.target)) {
   this.visible = false
   this.hide()
  }
 }
}

上面就是在 Popover show 的时候监听 document 的 click 事件,触发进入 hidePanel 方法,判断当前点击的 el 是否在 Popover 内部,如果不在,则手动 hide Popover ,并且移除监听事件。

这个还是蛮好理解的,我使用的也是这种方式,因为我的项目中需要这种需求的很少(好吧,就一个地方),所以我采用了这种方式。

第二种方式: 指令

<template>
 <div>
 <div class="show" v-show="show" v-clickoutside="handleClose">
 显示
 </div>
 </div>
</template>

<script>
const clickoutside = {
 // 初始化指令
 bind(el, binding, vnode) {
  function documentHandler(e) {
   // 这里判断点击的元素是否是本身,是本身,则返回
   if (el.contains(e.target)) {
    return false;
 }
   // 判断指令中是否绑定了函数
   if (binding.expression) {
    // 如果绑定了函数 则调用那个函数,此处binding.value就是handleClose方法
    binding.value(e);
   }
 }
  // 给当前元素绑定个私有变量,方便在unbind中可以解除事件监听
  el.__vueClickOutside__ = documentHandler;
  document.addEventListener('click', documentHandler);
 },
 update() {},
 unbind(el, binding) {
  // 解除事件监听
  document.removeEventListener('click', el.__vueClickOutside__);
  delete el.__vueClickOutside__;
 },
};
export default {
 name: 'HelloWorld',
 data() {
  return {
   show: true,
  };
 },
 directives: {clickoutside},
 methods: {
  handleClose(e) {
   this.show = false;
  },
 },
};
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
.show {
 width: 100px;
 height: 100px;
 background-color: red;
}
</style>

上面这种是网上比较火的一种方式(实际我没有测试过),其实思路还是那个思路 (给document增加一个click事件监听,当发生click事件的时候判断是否点击的当前对象,不是就隐藏),优点就是可以封装成全局/局部的指令,可多处使用。

下面简单介绍下 vue 指令

一个指令定义对象可以提供如下几个钩子函数 (均为可选):

  • bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。
  • inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。
  • update:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新 (详细的钩子函数参数见下)。
  • componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用。
  • unbind:只调用一次,指令与元素解绑时调用。

第三种方式:遮罩

<template>
 <div>
  <div class="mask" v-if="showModal" @click="showModal=false"></div>
  <div class="pop" v-if="showModal">
    <button @click="showModal=false" class="btn">点击出现弹框</button>
  </div>
  <button @click="showModal=true" class="btn">点击出现弹框</button>
 </div>
</template>

<script>
export default {
 data() {
  return {
   showModal: false
  };
 }
};
</script>

<style scoped>
.mask {
 background-color: #000;
 opacity: 0.3;
 position: fixed;
 top: 0;
 left: 0;
 width: 100%;
 height: 100%;
 z-index: 1
}
.pop {
 background-color: #fff;

 position: fixed;
 top: 100px;
 left: 300px;
 width: calc(100% - 600px);
 height:calc(100% - 200px);
 z-index: 2
}
.btn {
 background-color: #fff;
 border-radius: 4px;
 border: 1px solid blue;
 padding: 4px 12px;
}
</style>

上面这个就是添加一个看不见的遮罩替代 document ,点击遮罩就隐藏。但是要注意:mask(遮罩)层的层级(z-index)要比弹出的pop的层级低。

总结

以上所述是小编给大家介绍的Vue 实现点击空白处隐藏某节点的三种方式,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对我们网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

(0)

相关推荐

  • vue通过指令(directives)实现点击空白处收起下拉框

    日常开发中有时会有这样的需求,就是展开下拉框的时候,通过点击空白处,可以实现让下拉框收回.这里我们通过vue2.0中的自定义指令来简单实现. 貌似截图尺寸有点大(╯﹏╰) vue自定义指令 解释(参考官方文档) 除了核心功能默认内置的指令 (v-model 和 v-show),Vue 也允许注册自定义指令.注意,在 Vue2.0 中,代码复用和抽象的主要形式是组件.然而,有的情况下,你仍然需要对普通 DOM 元素进行底层操作,这时候就会用到自定义指令. 举例: 我们要让这样一个输入框在页面加载的

  • 详解vue中点击空白处隐藏div的实现(用指令实现)

    简单想应该怎么实现? 1.肯定是给document增加一个click事件监听 2.当发生click事件的时候判断是否点击的当前对象 结合着本思路和指令咱们来实现. 简单介绍vue指令 一个指令定义对象可以提供如下几个钩子函数 (均为可选): bind:只调用一次,指令第一次绑定到元素时调用.在这里可以进行一次性的初始化设置. inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中). update:所在组件的 VNode 更新时调用,但是可能发生在其子 VNod

  • Vue 实现点击空白处隐藏某节点的三种方式(指令、普通、遮罩)

    在项目中往往会有这样的需求: 弹出框(或Popover)在 show 后,点击空白处可以将其 hide. 针对此需求,整理了三种实现方式,大家按实际情况选择. 当然,我们做项目肯定会用到 UI 框架,常见的 Element 中的组件提供了这样的方法. 但是,就算使用框架,有些时候还是要用到的,比如: Element 中的 Popover,当我们想使用手动方式(trigger 触发方式为 manual时)控制它的 show & hide 的时候,就要自己实现这个功能啦. 第一种方式:最普通的手动监

  • 总结IOS中隐藏软键盘的三种方式

    一.使用软键盘的 Done 键隐藏键盘 出发软键盘隐藏最常用的事件是文本框的 Did End on Exit,它在用户按软键盘中的 Done 键时发生.选中一个UITextField控件,点击鼠标右键弹出面板,鼠标左键按住 Did End on Exit 事件旁边的圆圈,然后拖曳到右侧 .h 文件中,命名为 CloseTheKeyBoard,在 m 文件中具体实现如下图所示(此处同时显示 .h 文件与 .m 文件): 当页面中有很多个文本框时,如果每次都需要点文本框激活软键盘.输入后点击Retu

  • 在vue项目中(本地)使用iconfont字体图标的三种方式总结

    目录 vue项目中(本地)使用iconfont字体图标 开始使用 vue项目中(本地)使用iconfont字体图标 这里有使用前的准备和三种使用方式介绍,参考这里 还有 vue中手动封装iconfont组件(三种引用方式的封装) 开始使用 点击下载到本地 在了路径 src/assets 下新建文件夹 iconfont ,用来存放字体图标的本地文件 解压下载到本地的字体图标文件,放到 iconfont 文件夹下 如过项目中没有下载 css-loader 依赖包,就进行下载,否则会报错 npm in

  • 详解IOS点击空白处隐藏键盘的几种方法介绍

    IOS7 点击空白处隐藏键盘的几种方法,具体如下: iOS开发中经常要用到输入框,默认情况下点击输入框就会弹出键盘,但是必须要实现输入框return的委托方法才能取消键盘的显示,对于用户体验来说很不友好,我们可以实现点击键盘以外的空白区域来将键盘隐藏,以下我总结出了几种隐藏键盘的方法: 首先说明两种可以让键盘隐藏的Method: 1.[view endEditing:YES]  这个方法可以让整个view取消第一响应者,从而让所有控件的键盘隐藏. 2.[textFiled resignFirst

  • Android 中自定义Dialog样式的Activity点击空白处隐藏软键盘功能(dialog不消失)

    一.需求触发场景: 项目中需要开发带有EditText的Dialog显示,要求在编辑完EditText时,点击Dilog的空白处隐藏软键盘.但是Dialog不会消失.示例如下: 二.实现方法: 发布需求时,我个人曾想过直接通过new的方式直接创建Dialog,经过多次尝试,无法实现要求,所以采用将Activity设置为Dialog样式进行展示,调用方法实现需求.具体实现如下: 本次演示示例的工程结构: 2.1AndroidMainfest.xml配置文件 需要在配置文件中将需要显示为dialog

  • jquery如何实现点击空白处隐藏元素

    我们在网站开发的时候经常会有点击空白处去隐藏已有的元素,DIV或者其他,本次教给大家如何用jquery实现这个特效的方法. 一款jQuery点击空白处隐藏弹出层网页特效,点击按钮弹出层.点击页面空白处弹出层消失JS代码.主要功能是点击按钮弹出层显示,然后通过点击页面任意位置都能关闭弹出层显示效果,主要是$(document).click的操作应用.演示 Demo,效果源码: CSS代码: * { padding: 0; margin: 0; } #btnShow{ margin: 100px a

  • Flutter 全局点击空白处隐藏键盘实战

    老孟导读:为什么要实现点击空白处隐藏键盘?因为这是 iOS 平台的默认行为,Android 平台由于其弹出的键盘右上角默认带有关闭键盘的按钮,所以点击空白处不会隐藏键盘. 对于单个页面来说,通过为 TextField 添加 focusNode,点击空白处时使 TextField 失去焦点,实现如下: class DismissKeyboardDemo extends StatelessWidget { final FocusNode focusNode = FocusNode(); @overr

  • 详解QTreeWidget隐藏节点的两种方式

    目录 简述 方法一:直接隐藏式 方法二:间接隐藏式 结尾 简述 关于QTreeWidget隐藏节点有两种方式,一种是直接隐藏,一种是间接隐藏,但是两种方式各有差异,下面请听具体解说. 方法一:直接隐藏式 Qt助手里面提供了QTreeWidgetItem::setHidden方法,我们可以调用setHide(false)直接隐藏当前item.但是调用此方法会隐藏该节点下面的所有子节点. 图 1-1: 我们通过图1-2看到,调用此方法会将自己所有的孩子节点都给隐藏了,如果有这种需求的直接调用此方法即

  • vue项目刷新当前页面的三种方式(重载当前页面数据)

    目录 vue项目刷新当前页面的三种方式(重载当前页面数据) 一.this.$router.go(0) 二.location.reload() 三.用provide / inject 组合 PS:vue项目刷新当前页面的三种方法 vue项目刷新当前页面的三种方式(重载当前页面数据) 一.this.$router.go(0) 相当于F5刷新,这种方法虽然代码很少,只有一行,但是体验很差.页面会一瞬间的白屏,体验不是很好 二.location.reload() 这种也是一样,画面一闪,体验不是很好,相

  • vue组件传值的实现方式小结【三种方式】

    本文实例讲述了vue组件传值的实现方式.分享给大家供大家参考,具体如下: 前言 vue的组件传值分为三种方式:父传子.子传父.非父子组件传值 引用官网的一句话:父子组件的关系可以总结为 prop 向下传递,事件向上传递 父组件通过 prop 给子组件下发数据,子组件通过事件给父组件发送消息,如下图所示: 下面我们就开始用代码(一言不合就上代码)详细的介绍vue组件传值的三种方式 1.父传子 子组件的代码: <template> <div id="container"&

随机推荐