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 相关文章推荐
IE6下通过a标签点击切换图片的问题
Nov 14 Javascript
兼容IE、firefox以及chrome的js获取时间(getFullYear)
Jul 04 Javascript
如何解决ligerUI布局时Center中的Tab高度大小
Nov 24 Javascript
js获取iframe中的window对象的实现方法
May 20 Javascript
jquery把int类型转换成字符串类型的方法
Oct 07 Javascript
jQuery实现的浮动层div浏览器居中显示效果
Feb 03 Javascript
JS实现的简单拖拽功能示例
Mar 13 Javascript
微信小程序movable view移动图片和双指缩放实例代码
Aug 08 Javascript
浅谈vue项目优化之页面的按需加载(vue+webpack)
Dec 11 Javascript
mpvue中配置vuex并持久化到本地Storage图文教程解析
Mar 15 Javascript
ES6 Object.assign()的用法及其使用
Jan 18 Javascript
浅谈克隆 JavaScript
Nov 02 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和ACCESS写聊天室(五)
2006/10/09 PHP
php分页代码学习示例分享
2014/02/20 PHP
PHP实现链式操作的三种方法详解
2017/11/16 PHP
PHP守护进程化在C和PHP环境下的实现
2017/11/21 PHP
laravel 出现command not found问题的解决方案
2019/10/23 PHP
jQuery判断div随滚动条滚动到一定位置后停止
2014/04/02 Javascript
jquery.validate提示错误信息位置方法
2016/01/22 Javascript
AngularJS基础 ng-src 指令简单示例
2016/08/03 Javascript
javascript函数中的3个高级技巧
2016/09/22 Javascript
Bootstrap禁用响应式布局的实现方法
2017/03/09 Javascript
前端构建工具之gulp的配置与搭建详解
2017/06/12 Javascript
微信小程序wx.getImageInfo()如何获取图片信息
2018/01/26 Javascript
Vue刷新修改页面中数据的方法
2018/09/16 Javascript
微信小程序实现富文本图片宽度自适应的方法
2019/01/20 Javascript
详解vue中v-model和v-bind绑定数据的异同
2020/08/10 Javascript
vue实现tab栏点击高亮效果
2020/08/19 Javascript
[01:05:40]VG vs Newbee 2018国际邀请赛小组赛BO2 第二场 8.17
2018/08/20 DOTA
在python的WEB框架Flask中使用多个配置文件的解决方法
2014/04/18 Python
Python实现动态加载模块、类、函数的方法分析
2017/07/18 Python
详解Python异常处理中的Finally else的功能
2017/12/29 Python
python smtplib模块自动收发邮件功能(一)
2018/05/22 Python
python Django里CSRF 对应策略详解
2019/08/05 Python
python 将dicom图片转换成jpg图片的实例
2020/01/13 Python
python中图像通道分离与合并实例
2020/01/17 Python
在CentOS7下安装Python3教程解析
2020/07/09 Python
Python 3.9的到来到底是意味着什么
2020/10/14 Python
通过实例解析python and和or使用方法
2020/11/14 Python
Python中过滤字符串列表的方法
2020/12/22 Python
HTML5 Canvas标签使用收录
2009/07/07 HTML / CSS
酒吧副总经理岗位职责
2013/12/10 职场文书
大学生职业生涯规划书范文
2014/01/04 职场文书
国际商务专业职业生涯规划书范文
2014/01/17 职场文书
求职信的最佳写作思路
2014/02/01 职场文书
2014新课程改革心得体会
2014/03/10 职场文书
实名检举信范文
2015/03/02 职场文书
python实现Thrift服务端的方法
2021/04/20 Python