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 相关文章推荐
浅谈关于JavaScript的语言特性分析
Apr 11 Javascript
非html5实现js版弹球游戏示例代码
Sep 22 Javascript
JavaScript利用构造函数和原型的方式模拟C#类的功能
Mar 06 Javascript
JavaScript Length 属性的总结
Nov 02 Javascript
javascript省市区三级联动下拉框菜单实例演示
Nov 29 Javascript
基于JavaScript实现下拉列表左右移动代码
Feb 07 Javascript
微信小程序实现倒计时调用相机自动拍照功能
Jun 10 Javascript
jQuery解析json格式数据示例
Sep 01 jQuery
详解Vue Elementui中的Tag与页面其它元素相互交互的两三事
Sep 25 Javascript
通过npm或yarn自动生成vue组件的方法示例
Feb 12 Javascript
layui加载数据显示loading加载完成loading消失的实例代码
Sep 23 Javascript
Vue强制组件重新渲染的方法讨论
Feb 03 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
一个用mysql_odbc和php写的serach数据库程序
2006/10/09 PHP
PHP与MYSQL中UTF8编码的中文排序实例
2014/10/21 PHP
thinkphp配置连接数据库技巧
2014/12/02 PHP
Jquery实现自定义窗口随意的拖拽
2014/03/12 Javascript
JS实现至少包含字母、大小写数字、字符的密码等级的两种方法
2015/02/03 Javascript
jQuery Validate插件实现表单强大的验证功能
2015/12/18 Javascript
JavaScript通过代码调用Flash显示的方法
2016/02/02 Javascript
CentOS 安装NodeJS V8.0.0的方法
2017/06/15 NodeJs
Vue 项目代理设置的优化
2018/04/17 Javascript
vue自定义一个v-model的实现代码
2018/06/21 Javascript
微信小程序实现多选功能
2018/11/04 Javascript
node.js 基于cheerio的爬虫工具的实现(需要登录权限的爬虫工具)
2019/04/10 Javascript
手把手教你使用TypeScript开发Node.js应用
2019/05/06 Javascript
layui自己添加图片按钮并点击跳转页面的例子
2019/09/14 Javascript
Vue结合路由配置递归实现菜单栏功能
2020/06/16 Javascript
前端使用crypto.js进行加密的函数代码
2020/08/16 Javascript
Vue过滤器,生命周期函数和vue-resource简单介绍
2021/01/12 Vue.js
Python常用的日期时间处理方法示例
2015/02/08 Python
python将文本转换成图片输出的方法
2015/04/28 Python
Python3 导入上级目录中的模块实例
2019/02/16 Python
Django中在xadmin中集成DjangoUeditor过程详解
2019/07/24 Python
Python如何调用外部系统命令
2019/08/07 Python
Python OrderedDict的使用案例解析
2019/10/25 Python
Python中低维数组填充高维数组的实现
2019/12/02 Python
python实现密码验证合格程序的思路详解
2020/06/01 Python
python如何使用代码运行助手
2020/07/03 Python
解决pycharm导入numpy包的和使用时报错:RuntimeError: The current Numpy installation (‘D:\\python3.6\\lib\\site-packa的问题
2020/12/08 Python
运动员获奖感言
2014/08/15 职场文书
员工生日活动方案
2014/08/24 职场文书
单位委托书格式范本
2014/09/29 职场文书
街道党工委党的群众路线教育实践活动对照检查材料思想汇报
2014/10/05 职场文书
2015年五一劳动节慰问信
2015/03/23 职场文书
2016大学自主招生推荐信范文
2015/03/23 职场文书
Golang 实现获取当前函数名称和文件行号等操作
2021/05/08 Golang
解决mysql:ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO/YES)
2021/06/26 MySQL
微信小程序中使用vant框架的具体步骤
2022/02/18 Javascript