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.post用法关于type设置问题补充
Jan 03 Javascript
javascript常见用法总结
May 22 Javascript
javascript实现滑动解锁功能
Dec 31 Javascript
jQuery使用CSS()方法给指定元素同时设置多个样式
Mar 26 Javascript
很全面的JavaScript常用功能汇总集合
Jan 22 Javascript
如何使用Bootstrap的modal组件自定义alert,confirm和modal对话框
Mar 01 Javascript
JavaScript模拟push
Mar 06 Javascript
JavaScript中循环遍历Array与Map的方法小结
Mar 12 Javascript
js拖拽的原型声明和用法总结
Apr 04 Javascript
JS控制TreeView的结点选择
Nov 11 Javascript
Omi v1.0.2发布正式支持传递javascript表达式
Mar 21 Javascript
JQuery Ajax跨域调用和非跨域调用问题实例分析
Apr 16 jQuery
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 skymvc 一款轻量、简单的php
2011/06/28 PHP
浅谈PHP变量作用域以及地址引用问题
2013/12/27 PHP
php实现的漂亮分页方法
2014/04/17 PHP
PHP中加密解密函数与DES加密解密实例
2014/10/17 PHP
php实现遍历多维数组的方法
2015/11/25 PHP
PHP文件操作实例总结【文件上传、下载、分页】
2018/12/08 PHP
php中关于换行的实例写法
2019/09/26 PHP
几行代码轻松搞定jquery实现flash8类似的连接效果
2007/05/03 Javascript
javascript 实现父窗口引用弹出窗口的值的脚本
2007/08/07 Javascript
javascript实现二分查找法实现代码
2007/11/12 Javascript
鼠标悬浮停留三秒后自动显示大图js代码
2014/09/09 Javascript
javascript实现简单查找与替换的方法
2015/07/22 Javascript
使用CamanJS在Web页面上处理图像的技巧
2015/08/18 Javascript
两种JavaScript的AES加密方式(可与Java相互加解密)
2016/08/02 Javascript
NodeJS实现客户端js加密
2017/01/09 NodeJs
JavaScript实现开关等效果
2017/09/08 Javascript
移动端效果之IndexList详解
2017/10/20 Javascript
jQuery动态添加元素无法触发绑定事件的解决方法分析
2018/01/02 jQuery
在vue项目中使用element-ui的Upload上传组件的示例
2018/02/08 Javascript
如何通过setTimeout理解JS运行机制详解
2019/03/23 Javascript
layui动态渲染生成左侧3级菜单的方法(根据后台返回数据)
2019/09/23 Javascript
微信小程序仿抖音视频之整屏上下切换功能的实现代码
2020/05/24 Javascript
vue实现前端分页完整代码
2020/06/17 Javascript
解决Element中el-date-picker组件不回填的情况
2020/11/07 Javascript
[13:16]INFAMOUS vs VGJ T BO3
2018/06/07 DOTA
Python实现动态添加属性和方法操作示例
2018/07/25 Python
解决pycharm工程启动卡住没反应的问题
2019/01/19 Python
pandas的to_datetime时间转换使用及学习心得
2019/08/11 Python
在pytorch中为Module和Tensor指定GPU的例子
2019/08/19 Python
Python requests获取网页常用方法解析
2020/02/20 Python
自我评价怎么写好呢?
2013/12/05 职场文书
酒店开业策划方案
2014/06/02 职场文书
优秀班主任申报材料
2014/12/16 职场文书
幼儿园学前班幼儿评语
2014/12/29 职场文书
预备党员转正党小组意见
2015/06/01 职场文书
解读MySQL的客户端和服务端协议
2021/05/10 MySQL