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 @@ + + + +