v-tooltip 自定义指令

在当前项目中,tooltip提示框的功能用的比较多,每次都得重写,这次直接做成指令,下次拿来即用~

效果图:

right
top
bottom
left

使用方法:

content: 提示内容
color:文字颜色
bgColor:背景颜色
pos:提示位置,默认top

<div class="box" v-tooltip="{content: 'top提示', color:'#fff', bgColor: '#ffba00', pos: 'top'}">top提示</div>
<div class="box" v-tooltip="{content: 'right提示', color:'white', bgColor: 'black', pos: 'right'}">right提示</div>
<div class="box" v-tooltip="{content: 'bottom提示', color:'white', bgColor: 'black', pos: 'bottom'}">bottom提示</div>
<div class="box" v-tooltip="{content: 'left提示', color:'white', bgColor: 'black', pos: 'left'}">left提示</div>

使用时,需要注意 box 元素样式不能是 overflow: hidden;,否则不显示

源码:

/**
 * content: '回到顶部',  提示文字
 * color:'white',       字体颜色
 * bgColor: 'black',    背景颜色
 * pos: 'left'          位置,默认top
 */
import Vue from "vue";
Vue.directive("tooltip", {
  bind(el, binding) {
    el.style.position = "relative";
    let tip = document.createElement("span");
    el.addEventListener("mouseover", function() {
      tip.style.display = "block";
    });
    el.addEventListener("mouseout", function() {
      tip.style.display = "none";
    });
    tip.className = "tooltip";
    // 提示框样式
    let css = {
      display: "none",
      position: "absolute",
    //   width: "100%",
      padding: "5px 10px",
      borderRadius: "4px",
      color: binding.value.color || "white",
      backgroundColor: binding.value.bgColor || "black",
      lineHeight: 1,
      textAlign: 'center',
      zIndex: 9999
    };
    let pos = setPosition(tip, binding.value.pos, binding.value.bgColor);
    for (const item in pos) {
      css[item] = pos[item];
    }
    tip.textContent = binding.value.content;
    setCss(tip, css);
    el.appendChild(tip);
  }
});
// 给元素赋值样式
function setCss(obj, css) {
  for (const attr in css) {
    obj.style[attr] = css[attr];
  }
}
// 设置提示框位置样式
function setPosition(tip, pos, color) {
  switch (pos) {
    case "left":
      tip.className += " left";
      document.styleSheets[0].insertRule(
        `.tooltip.left:before{
            content: '';
            position: absolute;
            right: -5px;
            top: 50%;
            transform: translateY(-50%);
            border-left: 5px solid ${color};
            border-top: 5px solid transparent;
            border-bottom: 5px solid transparent;
        }`,
        0
      );
      return { left: "0", top: "50%", transform: "translateX(-110%) translateY(-50%)" };
      break;
    case "right":
      tip.className += " right";
      document.styleSheets[0].insertRule(
        `.tooltip.right:before{
          content: '';
          position: absolute;
          left: -5px;
          top: 50%;
          transform: translateY(-50%);
          border-right: 5px solid ${color};
          border-top: 5px solid transparent;
          border-bottom: 5px solid transparent;
      }`,
        0
      );
      return { right: "0", top: "50%", transform: "translateX(110%) translateY(-50%)" };
      break;
    case "bottom":
      tip.className += " bottom";
      document.styleSheets[0].insertRule(
        `.tooltip.bottom:before{
          content: '';
          position: absolute;
          top: -5px;
          left: 50%;
          transform: translateX(-50%);
          border-bottom: 5px solid ${color};
          border-left: 5px solid transparent;
          border-right: 5px solid transparent;
      }`,
        0
      );
      return {
        bottom: "-5%",
        left: "50%",
        transform: "translateX(-50%) translateY(130%)"
      };
      break;
    case "top":
      tip.className += " top";
      document.styleSheets[0].insertRule(
        `.tooltip.top:before{
          content: '';
          position: absolute;
          bottom: -5px;
          left: 50%;
          transform: translateX(-50%);
          border-top: 5px solid ${color};
          border-left: 5px solid transparent;
          border-right: 5px solid transparent;
      }`,
        0
      );
      return {
        top: "-5%",
        left: "50%",
        transform: "translateX(-50%) translateY(-130%)"
      };
      break;
    //top
    default:
      tip.className += " top";
      document.styleSheets[0].insertRule(
        `.tooltip.top:before{
        content: '';
        position: absolute;
        bottom: -5px;
        left: 50%;
        transform: translateX(-50%);
        border-bottom: 5px solid ${color};
        border-left: 5px solid transparent;
        border-right: 5px solid transparent;
    }`,
        0
      );
      return {
        top: "-5%",
        left: "50%",
        transform: "translateX(-50%) translateY(-130%)"
      };
      break;
  }
}

还可以做进一步优化:
1、提示文字双向绑定
2、空三角样式

参考链接

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,839评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,543评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,116评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,371评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,384评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,111评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,416评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,053评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,558评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,007评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,117评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,756评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,324评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,315评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,539评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,578评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,877评论 2 345

推荐阅读更多精彩内容

  • day01­_起源和结构 结构:Xhtml xml 表现:CSS 行为:DOM ECMAScript 以上都属于W...
    Sakura_明妃阅读 1,166评论 0 1
  • 选择qi:是表达式 标签选择器 类选择器 属性选择器 继承属性: color,font,text-align,li...
    love2013阅读 2,303评论 0 11
  • 选择qi:是表达式 标签选择器 类选择器 属性选择器 继承属性: color,font,text-align,li...
    wzhiq896阅读 1,731评论 0 2
  • JavaScript 1. type 类型判断 isString (o) {//是否字符串 returnObjec...
    Mr_ZhangH阅读 624评论 0 1
  • 声明:以下问题出自于文章:江湖人称向前兄《人生一百问》。 1:你的人生理想是什么?小时候你的梦想是什么?现在呢? ...
    老姚又姚阅读 2,219评论 8 8