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 相关文章推荐
javascript将数组插入到另一个数组中的代码
Jan 10 Javascript
jQuery实现新消息闪烁标题提示的方法
Mar 11 Javascript
JavaScript使表单中的内容显示在屏幕上的方法
Jun 29 Javascript
浅谈JavaScript中null和undefined
Jul 09 Javascript
javascript闭包(Closure)用法实例简析
Nov 30 Javascript
简单的jQuery拖拽排序效果的实现(增强动态)
Feb 09 Javascript
webpack打包后直接访问页面图片路径错误的解决方法
Jun 17 Javascript
浅谈redux以及react-redux简单实现
Aug 28 Javascript
JSONP原理及应用实例详解
Sep 13 Javascript
koa中间件核心(koa-compose)源码解读分析
Jun 15 Javascript
如何在postman测试用例中实现断言过程解析
Jul 09 Javascript
react中props 的使用及进行限制的方法
Apr 28 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
PHP MemCached 高级缓存应用代码
2010/08/05 PHP
Zend Framework数据库操作技巧总结
2017/02/18 PHP
浅谈laravel 5.6 安装 windows上使用composer的安装过程
2019/10/18 PHP
Laravel框架源码解析之入口文件原理分析
2020/05/14 PHP
javascript中检测变量的类型的代码
2010/12/28 Javascript
各浏览器对click方法的支持差异小结
2011/07/31 Javascript
js用Date对象处理时间实现思路及代码
2013/01/31 Javascript
Javascript setInterval的两种调用方法(实例讲解)
2013/11/29 Javascript
js获取当前页面的url网址信息
2014/06/12 Javascript
js实现图片轮播效果
2015/12/19 Javascript
javascript使用Promise对象实现异步编程
2016/03/01 Javascript
JS随机洗牌算法之数组随机排序
2016/03/23 Javascript
bootstrap实现图片自动轮播
2016/12/21 Javascript
extjs简介_动力节点Java学院整理
2017/07/17 Javascript
Vue.js 表单控件操作小结
2018/03/29 Javascript
vue2.0学习之axios的封装与vuex介绍
2018/05/28 Javascript
vue3.0中的双向数据绑定方法及优缺点
2019/08/01 Javascript
layui--select使用以及下拉框实现键盘选择的例子
2019/09/24 Javascript
Vue实现input宽度随文字长度自适应操作
2020/07/29 Javascript
Webpack5正式发布,有哪些新特性
2020/10/12 Javascript
Python进程间通信之共享内存详解
2017/10/30 Python
Tensorflow中的placeholder和feed_dict的使用
2018/07/09 Python
解决TensorFlow训练模型及保存数量限制的问题
2021/03/03 Python
IE支持HTML5的解决方法
2009/10/20 HTML / CSS
html5简介及新增功能介绍
2020/05/18 HTML / CSS
Needle & Thread官网:英国仙女品牌
2018/01/13 全球购物
服务中心夜班服务员岗位职责
2013/11/27 职场文书
致400米运动员广播稿
2014/02/07 职场文书
公司开业庆典主持词
2014/03/21 职场文书
学校百日安全生产活动总结
2014/07/05 职场文书
领导干部对照检查材料
2014/08/24 职场文书
观后感格式
2015/06/19 职场文书
高中运动会广播稿
2015/08/19 职场文书
小学语文教师竞聘演讲稿范文
2019/08/09 职场文书
使用Pytorch实现two-head(多输出)模型的操作
2021/05/28 Python
React配置子路由的实现
2021/06/03 Javascript