Vue组件之Tooltip的示例代码


Posted in Javascript onOctober 18, 2017

前言

本文主要Alert 组件的大致框架, 提供少量可配置选项。 旨在大致提供思路

tooltip

常用于展示鼠标 hover 时的提示信息。

模板结构

<template>
 <div style="position:relative;">
  <span ref="trigger">
   <slot>
   </slot>
  </span>
  <div class="tooltip"
   v-bind:class="{
    'top':   placement === 'top',
    'left':  placement === 'left',
    'right':  placement === 'right',
    'bottom': placement === 'bottom',
    'disable': type === 'disable',
    'delete': type === 'delete',
    'visible': show === true 
   }"
   ref="popover"
   role="tooltip">
   <div class="tooltip-arrow"></div>
   <div class="tooltip-inner">
    <slot name="content" v-html="content"></slot>
   </div>
  </div>
 </div>
</template>

大致结构DOM结构 一个div 包含 箭头 及 气泡内容。

v-bind中可选tooltip位置,是否禁用,及显示隐藏

slot 差值供自定义 默认接收content内容

script

import EventListener from '../utils/EventListener.js';

export default {
 props: {
  // 需要监听的事件
  trigger: {
   type: String,
   default: 'click'
  },
  effect: {
   type: String,
   default: 'fadein'
  },
  title: {
   type: String
  },
  // toolTip消息提示
  content: {
   type: String
  },
  header: {
   type: Boolean,
   default: true
  },
  placement: {
   type: String
  }
 },
 data() {
  return {
   // 通过计算所得 气泡位置 
   position: {
    top: 0,
    left: 0
   },
   show: true
  };
 },
 watch: {
  show: function(val) {
   if (val) {
    const popover = this.$refs.popover;
    const triger = this.$refs.trigger.children[0];
    // 通过placement计算出位子
    switch (this.placement) {
     case 'top' :
      this.position.left = triger.offsetLeft - popover.offsetWidth / 2 + triger.offsetWidth / 2;
      this.position.top = triger.offsetTop - popover.offsetHeight;
      break;
     case 'left':
      this.position.left = triger.offsetLeft - popover.offsetWidth;
      this.position.top = triger.offsetTop + triger.offsetHeight / 2 - popover.offsetHeight / 2;
      break;
     case 'right':
      this.position.left = triger.offsetLeft + triger.offsetWidth;
      this.position.top = triger.offsetTop + triger.offsetHeight / 2 - popover.offsetHeight / 2;
      break;
     case 'bottom':
      this.position.left = triger.offsetLeft - popover.offsetWidth / 2 + triger.offsetWidth / 2;
      this.position.top = triger.offsetTop + triger.offsetHeight;
      break;
     default:
      console.log('Wrong placement prop');
    }
    popover.style.top = this.position.top + 'px';
    popover.style.left = this.position.left + 'px';
   }
  }
 },
 methods: {
  toggle() {
   this.show = !this.show;
  }
 },
 mounted() {
  if (!this.$refs.popover) return console.error("Couldn't find popover ref in your component that uses popoverMixin.");
  // 获取监听对象
  const triger = this.$refs.trigger.children[0];
  // 根据trigger监听特定事件
  if (this.trigger === 'hover') {
   this._mouseenterEvent = EventListener.listen(triger, 'mouseenter', () => {
    this.show = true;
   });
   this._mouseleaveEvent = EventListener.listen(triger, 'mouseleave', () => {
    this.show = false;
   });
  } else if (this.trigger === 'focus') {
   this._focusEvent = EventListener.listen(triger, 'focus', () => {
    this.show = true;
   });
   this._blurEvent = EventListener.listen(triger, 'blur', () => {
    this.show = false;
   });
  } else {
   this._clickEvent = EventListener.listen(triger, 'click', this.toggle);
  }
  this.show = !this.show;
 },
 // 在组件销毁前移除监听,释放内存
 beforeDestroy() {
  if (this._blurEvent) {
   this._blurEvent.remove();
   this._focusEvent.remove();
  }
  if (this._mouseenterEvent) {
   this._mouseenterEvent.remove();
   this._mouseleaveEvent.remove();
  }
  if (this._clickEvent) this._clickEvent.remove();
 }
};
// EventListener.js
const EventListener = {
 /**
  * Listen to DOM events during the bubble phase.
  *
  * @param {DOMEventTarget} target DOM element to register listener on.
  * @param {string} eventType Event type, e.g. 'click' or 'mouseover'.
  * @param {function} callback Callback function.
  * @return {object} Object with a `remove` method.
  */
 listen(target, eventType, callback) {
  if (target.addEventListener) {
   target.addEventListener(eventType, callback, false);
   return {
    remove() {
     target.removeEventListener(eventType, callback, false);
    }
   };
  } else if (target.attachEvent) {
   target.attachEvent('on' + eventType, callback);
   return {
    remove() {
     target.detachEvent('on' + eventType, callback);
    }
   };
  }
 }
};

export default EventListener;

封装的事件监听

使用

使用content属性来决定hover时的提示信息。由placement属性决定展示效果:placement属性值为:方向-对齐位置;四个方向:top、left、right、bottom。trigger属性用于设置触发tooltip的方式,默认为hover。

<d-tooltip content="我是tooltip">
 <d-button type="text">鼠标移动到我上面试试</d-button>
</d-tooltip>
<d-tooltip content="我是tooltip" trigger="click">
 <d-button type="text">点我试试</d-button>
</d-tooltip>

content内容分发

设置一个名为content的slot。

<d-tooltip>
 <d-button type="text">鼠标移动到我上面试试</d-button>
 <p slot="content" class="tooltip-content">我是内容分发的conent。</p>
</d-tooltip>

Attributes

参数 说明 类型 可选值 默认值
content 显示的内容,也可以通过 slot#content 传入 DOM String
placement Tooltip 的出现位置 String top/right/bottom/left top
trigger tooltip触发方式 String hover

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
Extjs入门之动态加载树代码
Apr 09 Javascript
jquery一般方法介绍 入门参考
Jun 21 Javascript
jquery 操作DOM案例代码分享
Apr 05 Javascript
javascript学习(二)javascript常见问题总结
Jan 02 Javascript
js获得地址栏?问号后参数的方法
Aug 08 Javascript
基于jQuery实现的图片切换焦点图整理
Dec 07 Javascript
解析JavaScript模仿块级作用域
Dec 29 Javascript
Angular 4.x 路由快速入门学习
May 03 Javascript
laravel5.3 vue 实现收藏夹功能实例详解
Jan 21 Javascript
vue.js template模板的使用(仿饿了么布局)
Aug 13 Javascript
JS数组扁平化、去重、排序操作实例详解
Feb 24 Javascript
VUE和Antv G6实现在线拓扑图编辑操作
Oct 28 Javascript
JS正则表达式完美实现身份证校验功能
Oct 18 #Javascript
详解vue项目首页加载速度优化
Oct 18 #Javascript
JS简单实现滑动加载数据的方法示例
Oct 18 #Javascript
详解cordova打包成webapp的方法
Oct 18 #Javascript
prototype.js简单实现ajax功能示例
Oct 18 #Javascript
浅谈JS函数节流防抖
Oct 18 #Javascript
用vue封装插件并发布到npm的方法步骤
Oct 18 #Javascript
You might like
多人战的战术与战略
2020/03/04 星际争霸
PHP初学者头疼问题总结
2006/10/09 PHP
从PHP的源码中深入了解stdClass类
2014/04/18 PHP
CI框架Session.php源码分析
2014/11/03 PHP
完美解决phpdoc导出文档中@package的warning及Error的错误
2016/05/17 PHP
Docker 如何布置PHP开发环境
2016/06/21 PHP
thinkphp实现分页显示功能
2016/12/03 PHP
PHP PDOStatement::errorInfo讲解
2019/01/31 PHP
php微信扫码支付 php公众号支付
2019/03/24 PHP
JavaScript null和undefined区别分析
2009/10/14 Javascript
指定位置如果有图片显示图片,无图片显示广告的JS
2010/06/05 Javascript
js/jquery获取浏览器窗口可视区域高度和宽度以及滚动条高度实现代码
2012/12/17 Javascript
javascript 数字格式化输出的实现代码
2013/12/10 Javascript
js全选按钮的实现方法
2015/11/17 Javascript
js实现瀑布流的三种方式比较
2020/06/28 Javascript
微信小程序 video组件详解
2016/10/25 Javascript
jQuery+json实现动态创建复杂表格table的方法
2016/10/25 Javascript
js使用highlight.js高亮你的代码
2017/08/18 Javascript
JS加密插件CryptoJS实现的DES加密示例
2018/08/16 Javascript
js实现小球在页面规定的区域运动
2020/06/16 Javascript
Nodejs实现微信分账的示例代码
2021/01/19 NodeJs
python获取本地计算机名字的方法
2015/04/29 Python
python3中dict(字典)的使用方法示例
2017/03/22 Python
python读取excel表格生成erlang数据
2017/08/26 Python
python使用正则表达式来获取文件名的前缀方法
2018/10/21 Python
python使用suds调用webservice接口的方法
2019/01/03 Python
python设计tcp数据包协议类的例子
2019/07/23 Python
python中的itertools的使用详解
2020/01/13 Python
PyTorch加载自己的数据集实例详解
2020/03/18 Python
HTML4和HTML5之间除了相似以外的10个主要不同
2012/12/13 HTML / CSS
政府班子四风问题整改措施思想汇报
2014/10/08 职场文书
道德模范事迹材料
2014/12/20 职场文书
综合办公室岗位职责
2015/04/11 职场文书
因家庭原因离职的辞职信范文
2015/05/12 职场文书
初三化学教学反思
2016/02/22 职场文书
Spring this调用当前类方法无法拦截的示例代码
2022/03/20 Java/Android