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


Posted in Javascript onOctober 23, 2019

在项目中往往会有这样的需求: 弹出框(或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 实现点击空白处隐藏某节点的三种方式,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

Javascript 相关文章推荐
js 异步处理进度条
Apr 01 Javascript
禁止拷贝网页内容的js代码
Jan 22 Javascript
jquery重复提交请求的原因浅析
May 23 Javascript
用JS实现图片轮播效果代码(一)
Jun 26 Javascript
bootstrap与Jquery UI 按钮样式冲突的解决办法
Sep 23 Javascript
mvc 、bootstrap 结合分布式图简单实现分页
Oct 10 Javascript
js实现符合国情的日期插件详解
Jan 19 Javascript
如何在 Vue.js 中使用第三方js库
Apr 25 Javascript
Angular.js实现动态加载组件详解
May 28 Javascript
使用easyui从servlet传递json数据到前端页面的两种方法
Sep 05 Javascript
vue简单练习 桌面时钟的实现代码实例
Sep 19 Javascript
从源码角度来回答keep-alive组件的缓存原理
Jan 18 Javascript
p5.js实现动态图形临摹
Oct 23 #Javascript
浅析webpack-bundle-analyzer在vue-cli3中的使用
Oct 23 #Javascript
微信小程序 生成携带参数的二维码
Oct 23 #Javascript
使用p5.js临摹动态图形
Oct 23 #Javascript
浅析vue-cli3配置webpack-bundle-analyzer插件【推荐】
Oct 23 #Javascript
p5.js临摹动态图形实现方法详解
Oct 23 #Javascript
jQuery实现轮播图源码
Oct 23 #jQuery
You might like
linux下 C语言对 php 扩展
2008/12/14 PHP
php中的三元运算符使用说明
2011/07/03 PHP
fetchAll()与mysql_fetch_array()的区别详解
2013/06/05 PHP
PHP中常见的缓存技术实例分析
2015/09/23 PHP
yii2 数据库读写分离配置示例
2017/02/10 PHP
PHP静态成员变量和非静态成员变量详解
2017/02/14 PHP
PHP htmlspecialchars()函数用法与实例讲解
2019/03/08 PHP
取选中的radio的值
2010/01/11 Javascript
js 赋值包含单引号双引号问题的解决方法
2014/02/26 Javascript
png在IE6 下无法透明的解决方法汇总
2015/05/21 Javascript
在JavaScript中处理字符串之link()方法的使用
2015/06/08 Javascript
简介JavaScript中的setHours()方法的使用
2015/06/11 Javascript
Jquery技巧(必须掌握)
2016/03/16 Javascript
Jquery实现遮罩层的简单实例(就是弹出DIV周围都灰色不能操作)
2016/07/14 Javascript
js每隔两秒输出数组中的一项(实例)
2017/05/28 Javascript
JavaScript对JSON数据进行排序和搜索
2017/07/24 Javascript
angular+ionic返回上一页并刷新页面
2017/08/08 Javascript
chorme 浏览器记住密码后input黄色背景处理方法(两种)
2017/11/22 Javascript
Angular模版驱动表单的使用总结
2018/05/05 Javascript
详解Vue前端对axios的封装和使用
2019/04/01 Javascript
JS实现马赛克图片效果完整示例
2019/04/13 Javascript
深入浅析Vue 中 ref 的使用
2019/04/29 Javascript
vue vantUI tab切换时 list组件不触发load事件的问题及解决方法
2020/02/14 Javascript
python用10行代码实现对黄色图片的检测功能
2015/08/10 Python
python合并已经存在的sheet数据到新sheet的方法
2018/12/11 Python
Python读取csv文件实例解析
2019/12/30 Python
Tensorflow 1.0之后模型文件、权重数值的读取方式
2020/02/12 Python
Python argparse模块使用方法解析
2020/02/20 Python
全球独特生活方式产品和礼品购物网站:AHAlife
2018/09/18 全球购物
如何在.net Winform里面显示PDF文档
2012/09/11 面试题
财务部岗位职责
2013/11/19 职场文书
我的长生果教学反思
2014/04/28 职场文书
房地产开发项目建议书
2014/05/16 职场文书
2014年社区工会工作总结
2014/12/18 职场文书
Java8中Stream的一些神操作
2021/11/02 Java/Android
SpringCloud超详细讲解Feign声明式服务调用
2022/06/21 Java/Android