
本文介绍使用 Vue.js 将长段落按词拆分为独立 元素,并通过点击事件动态添加/移除高亮样式,实现单词级可交互、可持久化视觉反馈的效果。
本文介绍使用 vue.js 将长段落按词拆分为独立 `` 元素,并通过点击事件动态添加/移除高亮样式,实现单词级可交互、可持久化视觉反馈的效果。
在处理长文本的交互需求时,直接对整个
绑定 @click 无法精准定位被点击的“单词”——因为原生 DOM 事件的 e.target 默认指向最内层元素(如文本节点),而纯文本不支持样式控制。因此,核心思路是:预处理文本,将每个单词包裹进独立的 标签中,再为每个 绑定点击逻辑。
Vue 中推荐采用计算属性(computed)完成文本解析与 HTML 注入,避免在模板中硬编码正则替换。以下代码使用 \b(\w+?)\b 正则匹配单词边界内的字母数字组合(自动忽略标点),并用 $1 替换,确保每个单词成为可独立操作的 DOM 节点:
computed: {
pageContent() {
return this.page.replace(/\b(\w+?)\b/g, '<span>$1</span>');
}
}
在 @click="doSomething" 事件处理器中,e.target 即为被点击的 。我们通过检查 e.target.style.color 是否已设置来判断当前状态:若存在颜色,则还原为默认黑色;否则设为黄色(或通过 CSS 类统一管理样式更佳)。注意:直接操作 style 属性虽简单,但建议优先使用 classList.toggle() 配合 CSS 类,以提升可维护性与样式一致性。
✅ 推荐优化版(使用 CSS 类 + classList):
methods: {
doSomething(e) {
if (e.target.tagName === 'SPAN') {
e.target.classList.toggle('highlight');
console.log('Clicked word:', e.target.textContent);
}
}
}
对应 CSS:
.highlight {
background-color: #fff9c4; /* 浅黄色背景,比纯 yellow 更柔和 */
padding: 0 2px;
border-radius: 2px;
}
⚠️ 注意事项:
- v-html 渲染需确保内容可信,避免 XSS 风险(本例为静态文本,安全);
- 原始正则未处理连字符词(如 state-of-the-art),如需支持,可扩展为 /\b[\w\u4e00-\u9fa5]+(?:[-'][\w\u4e00-\u9fa5]+)*\b/g;
- 若需全局记录已点击单词,可在 data 中定义数组 highlightedWords: [],并在 toggle 时同步增删;
- Vue 3 用户请将 v-html 替换为 v-html(语法不变),但需注意 Composition API 下需在 setup() 中返回计算属性。
最终效果:用户单击任意单词,该词即高亮显示;再次点击则取消高亮。所有状态完全由 DOM 元素自身 class 控制,无需额外状态管理,简洁高效,适用于阅读辅助、词汇标记等场景。










