|
@@ -4,14 +4,15 @@ interface AutoTitleOptions {
|
|
|
always?: boolean; // 是否总是显示title
|
|
|
content?: string; // 自定义title内容
|
|
|
lines?: number; // 最大行数(支持多行省略)
|
|
|
+ addClass?: boolean; // 是否自动添加__text类名,默认为true
|
|
|
}
|
|
|
|
|
|
const autoTitle: Directive<HTMLElement, boolean | AutoTitleOptions | string> = {
|
|
|
mounted(el, binding) {
|
|
|
- observeElement(el, binding);
|
|
|
+ processElement(el, binding, true);
|
|
|
},
|
|
|
updated(el, binding) {
|
|
|
- observeElement(el, binding);
|
|
|
+ processElement(el, binding, false);
|
|
|
},
|
|
|
unmounted(el) {
|
|
|
const observer = (el as any)._autoTitleObserver;
|
|
@@ -22,14 +23,31 @@ const autoTitle: Directive<HTMLElement, boolean | AutoTitleOptions | string> = {
|
|
|
}
|
|
|
};
|
|
|
|
|
|
-function observeElement(el: HTMLElement, binding: DirectiveBinding) {
|
|
|
+function processElement(el: HTMLElement, binding: DirectiveBinding, isMounted: boolean) {
|
|
|
+ const options = parseBinding(binding);
|
|
|
+
|
|
|
+ // 自动添加__text类名(默认添加,可通过addClass: false禁用)
|
|
|
+ if (options.addClass !== false) {
|
|
|
+ el.classList.add(`__text-ellipsis${Number(options.lines) > 1 ? `-${options.lines}` : ''}`);
|
|
|
+ } else {
|
|
|
+ el.classList.remove(`__text-ellipsis${Number(options.lines) > 1 ? `-${options.lines}` : ''}`);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 初始化或更新观察者
|
|
|
+ if (isMounted) {
|
|
|
+ observeElement(el, options);
|
|
|
+ } else {
|
|
|
+ updateTitle(el, options);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+function observeElement(el: HTMLElement, options: AutoTitleOptions) {
|
|
|
// 先移除旧的观察者
|
|
|
const oldObserver = (el as any)._autoTitleObserver;
|
|
|
if (oldObserver) {
|
|
|
oldObserver.disconnect();
|
|
|
}
|
|
|
|
|
|
- const options = parseBinding(binding);
|
|
|
const observer = new ResizeObserver(() => {
|
|
|
updateTitle(el, options);
|
|
|
});
|
|
@@ -96,55 +114,4 @@ export default autoTitle;
|
|
|
// display: -webkit-box;
|
|
|
// -webkit-box-orient: vertical;
|
|
|
// overflow: hidden;
|
|
|
-// }
|
|
|
-
|
|
|
-
|
|
|
-// import type { Directive, DirectiveBinding } from 'vue';
|
|
|
-//
|
|
|
-// interface TitleOptions {
|
|
|
-// // 是否总是显示title,即使没有文本溢出
|
|
|
-// always?: boolean;
|
|
|
-// // 自定义title内容,如果不提供则使用元素文本
|
|
|
-// content?: string;
|
|
|
-// }
|
|
|
-//
|
|
|
-// const title: Directive<HTMLElement, boolean | TitleOptions | string> = {
|
|
|
-// mounted(el, binding) {
|
|
|
-// updateTitle(el, binding);
|
|
|
-// },
|
|
|
-// updated(el, binding) {
|
|
|
-// updateTitle(el, binding);
|
|
|
-// }
|
|
|
-// };
|
|
|
-//
|
|
|
-// function updateTitle(el: HTMLElement, binding: DirectiveBinding) {
|
|
|
-// const options = parseBinding(binding);
|
|
|
-//
|
|
|
-// if (options.always || el.scrollWidth > el.clientWidth) {
|
|
|
-// el.setAttribute('title', options.content || el.textContent?.trim() || '');
|
|
|
-// } else {
|
|
|
-// el.removeAttribute('title');
|
|
|
-// }
|
|
|
-// }
|
|
|
-//
|
|
|
-// function parseBinding(binding: DirectiveBinding): TitleOptions {
|
|
|
-// // 如果绑定值是布尔值
|
|
|
-// if (typeof binding.value === 'boolean') {
|
|
|
-// return { always: binding.value };
|
|
|
-// }
|
|
|
-//
|
|
|
-// // 如果绑定值是字符串
|
|
|
-// if (typeof binding.value === 'string') {
|
|
|
-// return { content: binding.value };
|
|
|
-// }
|
|
|
-//
|
|
|
-// // 如果绑定值是对象
|
|
|
-// if (typeof binding.value === 'object') {
|
|
|
-// return binding.value;
|
|
|
-// }
|
|
|
-//
|
|
|
-// // 默认情况
|
|
|
-// return { always: false };
|
|
|
-// }
|
|
|
-//
|
|
|
-// export default title;
|
|
|
+// }
|