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();
}
效果: