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 相关文章推荐
MooTools 页面滚动浮动层智能定位实现代码
Aug 23 Javascript
javaScript如何生成xmlhttp
Dec 16 Javascript
JS数组(Array)处理函数整理
Dec 07 Javascript
微信小程序 http请求详细介绍
Oct 09 Javascript
JavaScript中动态向表格添加数据
Jan 24 Javascript
详解微信小程序Page中data数据操作和函数调用
Sep 27 Javascript
Angular2使用SVG自定义图表(条形图、折线图)组件示例
May 10 Javascript
微信JS-SDK实现微信会员卡功能(给用户微信卡包里发送会员卡)
Jul 25 Javascript
JS 设计模式之:单例模式定义与实现方法浅析
May 06 Javascript
解决vue组件销毁之后计时器继续执行的问题
Jul 21 Javascript
vuex中store存储store.commit和store.dispatch的用法
Jul 24 Javascript
ElementUI实现el-form表单重置功能按钮
Jul 21 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
UTF8编码内的繁简转换的PHP类
2009/07/09 PHP
PHP5.3与5.5废弃与过期函数整理汇总
2014/07/10 PHP
PHP实现根据时间戳获取周几的方法
2016/02/26 PHP
PHP简单获取随机数的常用方法小结
2017/06/07 PHP
PHP Socket网络操作类定义与用法示例
2017/08/30 PHP
csdn 论坛技术区平均给分功能
2009/11/07 Javascript
Javascript Ajax异步读取RSS文档具体实现
2013/12/12 Javascript
通过正则表达式实现表单验证是否为中文
2014/02/18 Javascript
js身份证判断方法支持15位和18位
2014/03/18 Javascript
Windows系统中安装nodejs图文教程
2015/02/28 NodeJs
JQuery鼠标移到小图显示大图效果的方法
2015/06/10 Javascript
理解javascript中的严格模式
2016/02/01 Javascript
JavaScript原生编写《飞机大战坦克》游戏完整实例
2017/01/04 Javascript
基于Bootstrap漂亮简洁的CSS3价格表(附源码下载)
2017/02/28 Javascript
vue.js开发环境搭建教程
2017/05/04 Javascript
bootstrap3使用bootstrap datetimepicker日期插件
2017/05/24 Javascript
前端开发不得不知的10个最佳ES6特性
2017/08/30 Javascript
原生js中ajax访问的实例详解
2017/09/19 Javascript
详解JSONObject和JSONArray区别及基本用法
2017/10/25 Javascript
利用JavaScript的%做隔行换色的实例
2017/11/25 Javascript
JavaScript常用截取字符串的三种方式用法区别实例解析
2018/05/15 Javascript
javascript将非数值转换为数值
2018/09/13 Javascript
轻松学习JavaScript函数中的 Rest 参数
2019/05/30 Javascript
解决Python中字符串和数字拼接报错的方法
2016/10/23 Python
python获取文件真实链接的方法,针对于302返回码
2018/05/14 Python
Python os.rename() 重命名目录和文件的示例
2018/10/25 Python
python中列表的切片与修改知识点总结
2019/07/23 Python
美国伊甸园兄弟种子公司:Eden Brothers
2018/07/01 全球购物
Linux管理员面试题 Linux admin interview questions
2016/07/08 面试题
汽车技术服务与营销专业推荐信
2013/11/29 职场文书
初中音乐教学反思
2014/01/12 职场文书
先进个人获奖感言
2014/01/24 职场文书
媒体宣传策划方案
2014/05/25 职场文书
Nginx反向代理及负载均衡如何实现(基于linux)
2021/03/31 Servers
Python基础之pandas数据合并
2021/04/27 Python
教你怎么用Python处理excel实现自动化办公
2021/04/30 Python