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 相关文章推荐
Js 导出table内容到Excel的简单实例
Nov 19 Javascript
html的DOM中Event对象onblur事件用法实例
Jan 21 Javascript
基于jQuery+JSON的省市二三级联动效果
Jun 05 Javascript
基于JavaScript实现快速转换文本语言(繁体中文和简体中文)
Mar 07 Javascript
微信小程序  wx.request合法域名配置详解
Nov 23 Javascript
Angular.JS判断复选框checkbox是否选中并实时显示
Nov 30 Javascript
jquery事件与绑定事件
Mar 16 Javascript
jQuery使用bind函数实现绑定多个事件的方法
Oct 11 jQuery
详解mpvue小程序中怎么引入iconfont字体图标
Oct 01 Javascript
JavaScript时间与时间戳的转换操作实例分析
Dec 07 Javascript
vue框架下部署上线后刷新报404问题的解决方案(推荐)
Apr 03 Javascript
jQuery 查找元素操作实例小结
Oct 02 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版(2)
2006/10/09 PHP
PHP函数常用用法小结
2010/02/08 PHP
php日期转时间戳,指定日期转换成时间戳
2012/07/17 PHP
php通过两层过滤获取留言内容的方法
2016/07/11 PHP
YII2框架中使用yii.js实现的post请求
2017/04/09 PHP
弹出广告特效代码(一个IP只弹出一次)
2007/05/11 Javascript
JavaScript中实现sprintf、printf函数
2015/01/27 Javascript
js实现支持手机滑动切换的轮播图片效果实例
2015/04/29 Javascript
jquery实现倒计时效果
2015/12/14 Javascript
Javascript的表单验证-揭开正则表达式的面纱
2016/03/18 Javascript
原生js仿jquery实现对Ajax的封装
2016/10/04 Javascript
jQuery插件HighCharts绘制2D带Label的折线图效果示例【附demo源码下载】
2017/03/08 Javascript
vue高德地图之玩转周边
2017/06/16 Javascript
jQuery.Form实现Ajax上传文件同时设置headers的方法
2017/06/26 jQuery
JS如何设置元素样式的方法示例
2017/08/28 Javascript
Vue2.0基于vue-cli+webpack父子组件通信(实例讲解)
2017/09/14 Javascript
jQuery访问浏览器本地存储cookie、localStorage和sessionStorage的基本用法
2017/10/20 jQuery
微信小程序switch开关选择器使用详解
2018/01/31 Javascript
详解使用VUE搭建后台管理系统(vue-cli更新至3.0)
2018/08/22 Javascript
微信小程序获取用户信息并保存登录状态详解
2019/05/10 Javascript
详解基于Wepy开发小程序插件(推荐)
2019/08/01 Javascript
详解利用nodejs对本地json文件进行增删改查
2019/09/20 NodeJs
webpack的 rquire.context用法实现工程自动化的方法
2020/02/07 Javascript
JS如何实现封装列表右滑动删除收藏按钮
2020/07/23 Javascript
Python新手实现2048小游戏
2015/03/31 Python
判断python字典中key是否存在的两种方法
2018/08/10 Python
Python参数解析模块sys、getopt、argparse使用与对比分析
2019/04/02 Python
Python字典中的值为列表或字典的构造实例
2019/12/16 Python
Pytorch对Himmelblau函数的优化详解
2020/02/29 Python
Python 如何创建一个简单的REST接口
2020/07/30 Python
python与js主要区别点总结
2020/09/13 Python
顶级宝石首饰网络零售商:Angara
2016/10/25 全球购物
抗震救灾标语
2014/06/26 职场文书
校园广播站开场白
2015/06/01 职场文书
2016年感恩节活动总结大全
2016/04/01 职场文书
Python中的 enumerate和zip详情
2022/05/30 Python