当前位置: 代码网 > it编程>前端脚本>Vue.js > 基于ElementUI实现v-tooltip指令的示例代码

基于ElementUI实现v-tooltip指令的示例代码

2024年10月28日 Vue.js 我要评论
文本溢出隐藏并使用tooltip提示的需求,相信在平时的开发中会经常遇到。常规做法一般是使用elementui的el-tooltip组件,在每次组件更新的时候去获取元素的宽度/高度判断是否被隐藏。受益

文本溢出隐藏并使用tooltip 提示的需求,相信在平时的开发中会经常遇到。

常规做法一般是使用 elementui 的 el-tooltip 组件,在每次组件更新的时候去获取元素的宽度/高度判断是否被隐藏。

受益于 element-plus的虚拟触发 tooltip 的实现,决定探究在 vue2 上也以一种简单的方式实现 tooltip 提示。

探究 tooltip 源码

源码地址:https://github.com/elemefe/element/blob/dev/packages/tooltip/src/main.js

render 阶段,可以看出 tooltip 组件会提取插槽中的第一个子元素进行渲染

  render(h) {
    // ....
    const firstelement = this.getfirstelement();
    if (!firstelement) return null;

    const data = firstelement.data = firstelement.data || {};
    data.staticclass = this.addtooltipclass(data.staticclass);

    return firstelement;
  },

所以在 mounted 阶段, $el 会获取到的其实就是传入插槽的第一个元素。

并且在这个阶段,会给元素添加上mouseentermouseleave的事件监听,来控制 hover 状态下是否显示 tooltip

mounted() {
    this.referenceelm = this.$el;
    if (this.$el.nodetype === 1) {
      this.$el.setattribute('aria-describedby', this.tooltipid);
      this.$el.setattribute('tabindex', this.tabindex);
      on(this.referenceelm, 'mouseenter', this.show);
      on(this.referenceelm, 'mouseleave', this.hide);
      // ...
}

函数式调用 tooltip

在了解了 el-tooltip 的运行原理之后,我们能够封装一个模板,并且支持函数式调用。

通过 getel 获取一个 dom 元素,以便在唤起 tooltip 时元素的所处位置。

<template>
  <el-tooltip ref="triggerref" :manual="true">
    <template #content>
      {{ internalcontent }}
    </template>
  </el-tooltip>
</template>

<script>
// useoverflowhidden 的逻辑自行定义
import { useoverflowhidden } from './use-overflow-hidden'
export default {
  name: 'tooltipfunction',
  props: {
    getel: {
      type: function,
      default: () => null
    },
    getcontent: {
      type: function,
      default: () => ''
    }
  },
  data() {
    return {
      internalcontent: '',
      ishover: false,
    }
  },
  mounted() {
    const el = this.getel()
    if (!el) return

    this.$refs.triggerref.referenceelm = el;

    el.addeventlistener('mousemove', this.onmouseenter, false)
    el.addeventlistener('mouseleave', this.onmouseleave, false)
  },
  methods: {
    onmouseenter() {
      if (!this.ishover && useoverflowhidden(this.getel())) {
        this.internalcontent = this.getcontent()
        this.ishover = true
        this.$refs.triggerref.showpopper = true
      }
    },
    onmouseleave() {
      if (this.ishover) {
        this.ishover = false;
        this.$refs.triggerref.showpopper = false
      }
    },
    ondestroy() {
      const el = this.getel()
      if (!el) return

      el.removeeventlistener('mousemove', this.onmouseenter)
      el.removeeventlistener('mouseleave', this.onmouseleave)
    }
  },
}

</script>

模版完成过后,我们还需要再写一个函数用来调用 tooltipfunction

import vue from 'vue'
import tooltipfunction from './tooltipfunction.vue'

function usetooltip(el) {
  const ctor = vue.extend(tooltipwrapper)
  const instance = new ctor({
    propsdata: {
      getcontent,
      getel: () => el,
    },
  })

  instance.$mount()
  return instance
}

在代码中,我们只需在 mounted 中对需要 tooltip 的元素进行一次注册即可。

<template>
    <div ref="dataref">foo</div>
</template>

<script>
import usetooltip from './use-tooltip.js'
export default {
    mounted() {
        const el = this.$refs.dataref
        if (el) {
           // 获取 content 的函数逻辑自行定义
           this.tooltipins = usetooltip(el, () => 'foo')
        }
    },
    beforedestory() {
        this.tooltipins?.ondestroy()
        this.tooltipins?.$destroy()
    }
}
</script>

自定义指令 v-tooltip

上述虽然实现了函数式调用 tooltip 的方式,但是还需要对每个元素进行 ref 声明获取 dom,以及组件销毁时 tooltip 的生命周期管理。vue 的自定义指令恰好能轻松解决这两件事情。

function setuptooltipdirection() {
  const tooltipsymbol = symbol('tooltip')
  vue.directive('tooltip', {
    bind(el: htmlelement) {
     // 这里我们使用 dom 元素上的 tooltip-content 作为 通信
      const instance = createtooltipfactory(el, () => el.getattribute('tooltip-content') || '')
      reflect.set(el, tooltipsymbol, instance)
    },
    unbind(el) {
      const ins = reflect.get(el, tooltipsymbol)
      if (!ins) return

      ins.ondestroy()
      ins.$destroy()
      reflect.set(el, tooltipsymbol, null)
    },
  })
}

在业务中,即可通过简单的指令实现 tooltip 的提示需求:

<template>
    <div v-tooltip tooltip-content="hello">hello</div>
</template>

到此这篇关于基于elementui实现v-tooltip指令的示例代码的文章就介绍到这了,更多相关elementui实现v-tooltip内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com