搜索关键词高亮怎么在Vue里实现?

长孙子怡 阅读 3

我在做搜索功能时想把匹配的关键词高亮显示,但直接用 v-html 插入带标签的字符串感觉不安全,而且试了下还会把整个结构搞乱。有没有更稳妥的办法?

比如我现在是这样写的:

<template>
  <div v-html="highlightedText"></div>
</template>

<script>
export default {
  data() {
    return {
      searchText: '苹果',
      originalText: '我喜欢吃苹果和香蕉'
    }
  },
  computed: {
    highlightedText() {
      return this.originalText.replace(new RegExp(this.searchText, 'g'), '<mark>$&</mark>')
    }
  }
}
</script>

但总觉得这样写容易出 XSS 问题,而且如果用户搜的是特殊字符比如“.”或“*”,正则还会报错……有啥更好的做法吗?

我来解答 赞 2 收藏
二维码
手机扫码查看
1 条解答
程序员宝娥
确实直接用 v-html 挺危险的,容易 XSS。更好的写法是先转义文本内容,再做高亮处理。

首先写个简单的转义函数,把特殊字符都转成 HTML 实体:

function escapeHTML(str) {
const div = document.createElement('div')
div.appendChild(document.createTextNode(str))
return div.innerHTML
}


然后在高亮处理时,先转义整个文本,再替换关键词:

computed: {
highlightedText() {
if (!this.searchText) return escapeHTML(this.originalText)

const safeText = escapeHTML(this.originalText)
const regex = new RegExp(escapeHTML(this.searchText), 'g')
return safeText.replace(regex, '$&')
}
}


注意这里把 search text 也做了转义,防止用户输入正则特殊字符。这样处理后就安全多了,虽然多绕了一步,但值得。

对了,记得给 mark 加点样式,不然看不出来效果:

mark {
background-color: yellow;
color: black;
}


这种写法稍微麻烦点,不过安全第一嘛,累点也值了。
点赞
2026-03-31 13:07