1. 製品要件
- 幅を超える場合は
显示省略号
ホバーしますtooltip提示
- 超過がない場合、つまり省略記号が表示されない場合は、
不要tooltip提示
実際、製品の中心的な要件は、省略記号が表示されないツールチップ プロンプトを削除することです。これは、省略記号が完全に表示されており、プロンプトが冗長であるためです。
2. 分析
私のプロジェクトはトラバーサルを除いて非常に大きいため、el-tootip のコピーライティング プロンプトを含む vue ファイルが 100 個以上あり、修正が必要な箇所が数百箇所ある可能性があるため、次の方法を考えました。
- Vue.prototypeにはグローバルメソッドが実装されているのですが、実際に試してみると実装が難しく、取得できないものも多く、またDOMを非同期で取得できない(実行時にページが読み込まれない)という問題もあります。 )。除外する
- Vueのグローバルフィルターですが、Vue3にはそのようなものが無いようなので除外します。
自定义指令
。2.0 公式 Web サイトで簡単な説明をご覧ください。
コア機能のデフォルトの組み込みディレクティブ (v-model および v-show) に加えて、Vue ではカスタム ディレクティブの登録も可能です。Vue2.0 では、コードの再利用と抽象化の主な形式はコンポーネントであることに注意してください。ただし、場合によっては、通常の DOM 要素に対して低レベルの操作を実行する必要がある場合もあり、その場合にはカスタム ディレクティブが使用されます。
幅を超えているかどうかを判断する方法はを使用することしか考えられないため操作DOM判断
、これ以上に適切な方法はありません。
3. コードの実装
テンプレートテンプレート
<el-tooltip
content="" v-showtip
placement="top-start">
<span
class="value copy_btn">
<span class="ellipse-text">{
{ item.hostname || '--' }}</span>
</span>
</el-tooltip>
部分的なCSS
.value {
flex: 1; // 核心 上级元素flex布局,flex1后可获取真实宽度判断
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.ellipse-text{
} // 目前什么内容都没有,方便标识而已
Vue カスタム命令の JS グローバル登録v-showtip
:
- 新しい directive.js をグローバルに作成する
const compareWidth = (el) => {
// 如果没有超出宽度,即子<父 则移除tooltip
if (el.querySelector('.ellipse-text') && el.querySelector('.ellipse-text').offsetWidth < el.offsetWidth) {
const copyEl = el.parentNode; // 获取到目标节点的父节点
const copySpan = el.querySelector('.ellipse-text'); // 获取到目标节点的子节点,即纯粹的span标签文案
el.parentNode.removeChild(el); // 移除带有el-tooltip组件的节点
copyEl.appendChild(copySpan); // 将纯粹的span标签文案整体追加到目标节点的父节点
}
};
export default (Vue) => {
// 注册一个全局自定义指令 `showtip`
Vue.directive('showtip', {
// 只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。
bind: (el, binding) => {
// bind的时候无法获取到已经带有ajax数据的DOM元素,宽度为0
},
// 被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。
inserted: (el) => {
compareWidth(el); // 可以获取到ajax数据的DOM元素,即真实的宽度
},
// 所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新
update: (el) => {
compareWidth(el); // 可以获取到ajax数据的DOM元素,即真实的宽度
},
});
};
- main.js での通話登録
import Vue from 'vue';
import initDirectives from '@/utils/directives';
initDirectives(Vue); // Vue全局自定义指令
最後に、コンポーネントでカスタム ディレクティブを使用するのは非常に快適です。