From dce6cad562f847d5a628f53d435492b1c8fbb4b4 Mon Sep 17 00:00:00 2001
From: Cell <1024@lruihao.cn>
Date: Tue, 20 Feb 2024 16:43:15 +0800
Subject: [PATCH] =?UTF-8?q?Feat:=20=E5=A2=9E=E5=8A=A0=20v-overflow-tooltip?=
=?UTF-8?q?=20=E6=8C=87=E4=BB=A4?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/App.vue | 2 +-
src/directives/overflow-tooltip.js | 79 ++++++++++++++++++++++++++++++
src/main.js | 3 ++
src/router.js | 6 +++
src/views/home.vue | 2 +-
src/views/overflow-tooltip.vue | 39 +++++++++++++++
6 files changed, 129 insertions(+), 2 deletions(-)
create mode 100644 src/directives/overflow-tooltip.js
create mode 100644 src/views/overflow-tooltip.vue
diff --git a/src/App.vue b/src/App.vue
index 4df0a7d..cecfe61 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -66,7 +66,7 @@
@click.prevent
/>
- {{ row.meta.description }}
+ {{ row.meta && row.meta.description }}
diff --git a/src/directives/overflow-tooltip.js b/src/directives/overflow-tooltip.js
new file mode 100644
index 0000000..3e0fc9d
--- /dev/null
+++ b/src/directives/overflow-tooltip.js
@@ -0,0 +1,79 @@
+const plugin = {
+ install(Vue) {
+ Vue.directive('overflow-tooltip', {
+ inserted: (el, binding, vnode) => {
+ // 设置内容
+ if (el.innerText === '') {
+ el.innerText = binding.value
+ }
+ // 设置元素样式
+ Object.assign(el.style, {
+ overflow: 'hidden',
+ textOverflow: 'ellipsis',
+ whiteSpace: 'nowrap',
+ })
+
+ const elComputed = document.defaultView.getComputedStyle(el, '')
+ const padding = parseInt(elComputed.paddingLeft.replace('px', '')) + parseInt(elComputed.paddingRight.replace('px', ''))
+ const range = document.createRange()
+ range.setStart(el, 0)
+ range.setEnd(el, el.childNodes.length)
+ const rangeWidth = range.getBoundingClientRect().width
+
+ console.log('vnode', vnode)
+
+ if (rangeWidth + padding > el.offsetWidth || el.scrollWidth > el.offsetWidth) {
+ // 鼠标移入时,将浮沉元素插入到 body 中
+ el.onmouseenter = function (e) {
+ // 创建浮层元素并设置样式
+ const vcTooltipDom = document.createElement('div')
+ Object.assign(vcTooltipDom.style, {
+ position: 'absolute',
+ background: '#303133',
+ color: '#fff',
+ fontSize: '12px',
+ zIndex: '2000',
+ padding: '10px',
+ borderRadius: '4px',
+ lineHeight: 1.2,
+ minHeight: '10px',
+ wordWrap: 'break-word',
+ })
+ // 设置 id 方便寻找
+ vcTooltipDom.setAttribute('id', 'vc-tooltip')
+ // 将浮层插入到 body 中
+ document.body.appendChild(vcTooltipDom)
+ // 浮层中的文字 通过属性值传递动态的显示文案
+ document.getElementById('vc-tooltip').innerHTML = binding.value
+ }
+ // 鼠标移动时,动态修改浮沉的位置属性
+ el.onmousemove = function (e) {
+ const vcTooltipDom = document.getElementById('vc-tooltip')
+ vcTooltipDom.style.top = e.clientY + 15 + 'px'
+ vcTooltipDom.style.left = e.clientX + 15 + 'px'
+ }
+ // 鼠标移出时将浮层元素销毁
+ el.onmouseleave = function () {
+ // 找到浮层元素并移出
+ const vcTooltipDom = document.getElementById('vc-tooltip')
+ vcTooltipDom && document.body.removeChild(vcTooltipDom)
+ }
+ }
+ }
+ })
+ }
+}
+
+
+let GlobalVue = null
+if (typeof window !== 'undefined') {
+ GlobalVue = window.Vue
+} else if (typeof global !== 'undefined') {
+ GlobalVue = global.Vue
+}
+
+if (GlobalVue) {
+ GlobalVue.use(plugin)
+}
+
+export default plugin
diff --git a/src/main.js b/src/main.js
index 93cefb9..407227d 100644
--- a/src/main.js
+++ b/src/main.js
@@ -9,6 +9,7 @@ import elTableSticky from '@cell-x/el-table-sticky'
import vueMinderEditor from 'vue-minder-editor-extended'
import ElCardCollapse from '@/components/ElCardCollapse.vue'
import Clickoutside from 'element-ui/src/utils/clickoutside'
+import overflowTooltip from '@/directives/overflow-tooltip'
// register svg component globally
Vue.component('SvgIcon', SvgIcon)
@@ -32,6 +33,8 @@ Vue.directive('focus', {
el.focus()
}
})
+// v-overflow-tooltip 指令,用于元素内容溢出时显示 tooltip
+Vue.use(overflowTooltip)
new Vue({
router,
diff --git a/src/router.js b/src/router.js
index 72bd4bc..0fc0cf9 100644
--- a/src/router.js
+++ b/src/router.js
@@ -59,6 +59,12 @@ const routes = [
meta: { description: '脑图编辑器 demo' },
component: () => import(/* webpackChunkName: "minderEditor" */ '@/views/minder-editor'),
},
+ {
+ path: '/overflow-tooltip',
+ name: 'overflowTooltip',
+ meta: { description: 'v-overflow-tooltip 指令' },
+ component: () => import(/* webpackChunkName: "overflowTooltip" */ '@/views/overflow-tooltip'),
+ },
{
path: '/set-height-adaptive',
name: 'setHeightAdaptive',
diff --git a/src/views/home.vue b/src/views/home.vue
index 89e7bbc..4fe3c00 100644
--- a/src/views/home.vue
+++ b/src/views/home.vue
@@ -29,7 +29,7 @@
@click.prevent
/>
- {{ row.meta.description }}
+ {{ row.meta && row.meta.description }}
diff --git a/src/views/overflow-tooltip.vue b/src/views/overflow-tooltip.vue
new file mode 100644
index 0000000..a66c834
--- /dev/null
+++ b/src/views/overflow-tooltip.vue
@@ -0,0 +1,39 @@
+
+
+
+
v-overflow-tooltip
+
+
+
+
+
el-tooltip
+
+ {{ content }}
+
+
+
+
+