使用背景
平常我们再给文案过长时显示省略号,并且鼠标hover后通过tooltip显示完整文案。如果不做处理,会出现没有触发省略号时,鼠标hover后也会出现tooltip组件。因为此时的操作计算为dom宽度的计算,因此通过封装全局自定义指令统一实现。
具体实现
在utils文件夹新建trunced.ts文件,封装指令逻辑
// 控制tooltip触发时机指令
import type { ObjectDirective } from 'vue'
const syncVar = (node, binding, vnode) => {
if (binding.arg) {
binding.value[binding.arg] = node.offsetWidth < node.scrollWidth
}
}
export const trunced: ObjectDirective = {
mounted(el: HTMLButtonElement, binding, vnode) {
syncVar(el, binding, vnode)
const ro = new ResizeObserver((entries) => {
entries[0].target && syncVar(el, binding, vnode)
})
ro.observe(el)
},
updated: function (el, binding, vnode) {
syncVar(el, binding, vnode)
},
}
在自定义指令文件夹/**/directives/index.ts文件夹下引入自定义指令
import { App } from 'vue'
// import setupPinia from './pinia'
// import setupCustomComponents from './globalComponents'
// import setupAssets from './resources'
// import setupDayjs from './dayjs'
// import setupMethods from './globalMethods'
import { setupDirectives } from './directives/index'
export function setupPlugins(app: App) {
// setupAssets()
// setupMethods(app)
// setupPinia(app)
// setupCustomComponents(app)
// setupDayjs()
setupDirectives(app)
}
注册指令
import { App } from 'vue'
// import setupPinia from './pinia'
// import setupCustomComponents from './globalComponents'
// import setupAssets from './resources'
// import setupDayjs from './dayjs'
// import setupMethods from './globalMethods'
import { setupDirectives } from './directives/index'
export function setupPlugins(app: App) {
// setupAssets()
// setupMethods(app)
// setupPinia(app)
// setupCustomComponents(app)
// setupDayjs()
setupDirectives(app)
}
组件内使用方式
- 给需要使用tootip的dom定义响应式变量
- 给dom定义出现省略号的固定样式
- 绑定自定义指令
<script setup lang="ts">
const obj = reactive({
sl: false,
value: '11111111',
})
</script>
<template>
<div class="container">
<el-tooltip :disabled="!obj.sl" :content="obj.value">
<div v-trunced:sl="obj" class="test">
{{ value }}
</div>
</el-tooltip>
<!-- 测试使用 -->
<input v-model="value" />
</div>
</template>
<style scoped lang="scss">
.test {
margin: 50px 0;
background-color: red;
color: #fff;
width: 15%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
</style>