vue 识别一个高亮组件全局
·
hightLight.js
import { ref, watch, nextTick } from 'vue';
// 共享关键词状态
const currentKeyword = ref('');
export const setGlobalHighlightKeyword = (keyword) => {
currentKeyword.value = (keyword || '').trim();
};
// 清除高亮
export const clearGlobalHighlight = (container = document.body) => {
const highlighted = container.querySelectorAll('span[style*="background: #555"]');
highlighted.forEach(span => {
if (span.parentNode) {
const textNode = document.createTextNode(span.textContent);
span.replaceWith(textNode);
}
});
};
const highlightNode = (node, keyword) => {
if (!keyword || !node?.textContent) return;
const parent = node.parentNode;
if (!parent || !parent.isConnected) return;
const text = node.textContent;
const escapedKeyword = keyword.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
const regex = new RegExp(`(${escapedKeyword})`, 'gi');
if (!regex.test(text)) return;
const temp = document.createElement('div');
text.split(regex).forEach(part => {
if (part.toLowerCase() === keyword.toLowerCase()) {
const span = document.createElement('span');
span.style.cssText = 'color:#ffff00;background: #555;font-weight: bold; font-size: 13px;';
span.textContent = part;
temp.appendChild(span);
} else {
temp.appendChild(document.createTextNode(part));
}
});
if (!node.parentNode) return;
const nextSibling = node.nextSibling;
node.replaceWith(temp);
if (nextSibling) {
while (temp.lastChild) {
parent.insertBefore(temp.lastChild, nextSibling);
}
} else {
while (temp.firstChild) {
parent.appendChild(temp.firstChild);
}
}
};
const walkAndHighlight = (element, keyword) => {
if (!element.isConnected && element !== document.body) return;
const walker = document.createTreeWalker(element, NodeFilter.SHOW_TEXT, null);
const nodes = [];
let node;
while (node = walker.nextNode()) {
const parent = node.parentNode;
if (
parent &&
['INPUT', 'TEXTAREA', 'SCRIPT', 'STYLE'].includes(parent.tagName) ||
parent.isContentEditable
) continue;
nodes.push(node);
}
// 逆序处理,避免 DOM 变化影响遍历
nodes.reverse().forEach(n => highlightNode(n, keyword));
};
export const GlobalHighlight = {
mounted(el) {
if (currentKeyword.value) {
clearGlobalHighlight(el);
walkAndHighlight(el, currentKeyword.value);
}
// 监听关键词变化
watch(currentKeyword, (newVal) => {
nextTick(() => {
if (el.isConnected) {
clearGlobalHighlight(el);
if (newVal) {
walkAndHighlight(el, newVal);
}
}
});
});
},
updated(el) {
nextTick(() => {
if (el.isConnected) {
clearGlobalHighlight(el);
if (currentKeyword.value) {
walkAndHighlight(el, currentKeyword.value);
}
}
});
},
unmounted(el) {
clearGlobalHighlight(el);
}
};
export default GlobalHighlight;
应用:main.js 中
import GlobalHighlight, { setGlobalHighlightKeyword } from "~/composables/globalHighlight"
vue文件中:
import { setGlobalHighlightKeyword,clearGlobalHighlight} from '~/composables/globalHighlight';
// 点击搜索按钮
const handleSearch = async () => {
await nextTick();
if (queryParams.ORDER_NO) { setGlobalHighlightKeyword(queryParams.ORDER_NO) }
if (queryParams.IVC_NO) { setGlobalHighlightKeyword(queryParams.IVC_NO) }
};
// 重置查询条件
const handleReset = () => {
clearGlobalHighlight();
}
效果: 
更多推荐


所有评论(0)