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 相关文章推荐
jquery 插件开发方法小结
Oct 23 Javascript
jQuery实现单行文字间歇向上滚动源代码
Jun 02 Javascript
使用jQuery实现input数值增量和减量的方法
Jan 24 Javascript
javascript中attachEvent用法实例分析
May 14 Javascript
JavaScript 正则表达式中global模式的特性
Feb 25 Javascript
JavaScript 函数的定义-调用、注意事项
Apr 16 Javascript
React学习笔记之条件渲染(一)
Jul 02 Javascript
基于vue中对鼠标划过事件的处理方式详解
Aug 22 Javascript
vue动画打包后失效问题的解决方法
Sep 18 Javascript
ES6基础之数组和对象的拓展实例详解
Aug 22 Javascript
uploadify插件实现多个图片上传并预览
Sep 30 Javascript
如何基于JavaScript判断图片是否加载完成
Dec 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
php反弹shell实现代码
2009/04/22 PHP
PHP 透明水印生成代码
2012/08/27 PHP
探讨:使用XMLSerialize 序列化与反序列化
2013/06/08 PHP
php生成随机颜色的方法
2014/11/13 PHP
php通过会话控制实现身份验证实例
2016/10/18 PHP
用js生产批量批处理执行命令
2008/07/28 Javascript
23个Javascript弹出窗口特效整理
2011/02/25 Javascript
javascript简单实现命名空间效果
2014/03/06 Javascript
javascript面向对象之this关键词用法分析
2015/01/13 Javascript
jQuery获取上传文件的名称的正则表达式
2015/05/21 Javascript
浅谈angularJS中的事件
2016/07/12 Javascript
使用JS批量选中功能实现更改数据库中的status状态值(批量展示)
2016/11/22 Javascript
canvas实现流星雨的背景效果
2017/01/13 Javascript
JS使用面向对象技术实现的tab选项卡效果示例
2017/02/28 Javascript
Cookies 和 Session的详解及区别
2017/04/21 Javascript
vue-resource请求实现http登录拦截或者路由拦截的方法
2018/07/11 Javascript
jQuery实现的简单日历组件定义与用法示例
2018/12/24 jQuery
如何使用electron-builder及electron-updater给项目配置自动更新
2018/12/24 Javascript
python排序方法实例分析
2015/04/30 Python
老生常谈python的私有公有属性(必看篇)
2017/06/09 Python
python利用跳板机ssh远程连接redis的方法
2019/02/19 Python
python绘制玫瑰的实现代码
2020/03/02 Python
python 在右键菜单中加入复制目标文件的有效存放路径(单斜杠或者双反斜杠)
2020/04/08 Python
Python 如何反方向迭代一个序列
2020/07/28 Python
python实现测试工具(一)——命令行发送get请求
2020/10/19 Python
HTML5 实现一个访问本地文件的实例
2012/12/13 HTML / CSS
学校门卫工作职责
2013/12/07 职场文书
你懂得怎么写自荐信吗?
2013/12/27 职场文书
爱情寄语大全
2014/04/09 职场文书
幼儿园小班工作总结2015
2015/04/25 职场文书
给下属加薪申请报告
2015/05/15 职场文书
工程竣工验收申请报告
2015/05/15 职场文书
2015年外贸业务员工作总结范文
2015/05/23 职场文书
冲出亚马逊观后感
2015/06/03 职场文书
Nginx+SpringBoot实现负载均衡的示例
2021/03/31 Servers
python接口测试返回数据为字典取值方式
2022/02/12 Python