如何在vuejs中不呈现v-html中的html标签?

bz4sfanl  于 2023-03-09  发布在  Vue.js
关注(0)|答案(3)|浏览(362)

我只想把匹配的字符串加粗。比如,我有一个字符串"Hello,World!",用户搜索了"hello"。我想把这样的东西,"Hello,World!"。
我试过了,

const search = ref('hello')
function boldText(text) {
    return text.replace(search.value, `<b>${search.value}</b>`)
}
<p v-html="boldText('Hello, World!')"></p>

但问题是它是大小写敏感的,如果我的字符串包含html标签,它会呈现,如果我的字符串是<div>Hello, World</div>,它不会显示div标签,因为我使用的是v-html
有没有办法解决这两个问题?

dxxyhpgq

dxxyhpgq1#

您可以尝试以下代码片段::

const { ref, nextTick } = Vue
const app = Vue.createApp({
  setup() {
    const search = ref('hello')
    function boldText(text) {
        return text.replace(new RegExp('(' + search.value + ')',"ig"), '<b>$1</b>');
    }
    return { search, boldText }
  },
})
app.mount('#demo')
<script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>
<div id="demo">
  <p v-html="boldText('Hello, World!')"></p>
</div>
0vvn1miw

0vvn1miw2#

如果可以的话,请尽量避免使用v-html,而使用渲染函数。
这是我会创建一个单独的组件来做的事情。使用插槽允许您定制如何标记匹配的文本和设置样式,而不是硬编码<b>标记。

// https://stackoverflow.com/a/9310752/734040
function escapeRegExp(text) {
  return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&')
}

const app = Vue.createApp({
  setup() {
    const text = Vue.ref('Hello world!')
    const query = Vue.ref('hello')
    
    return { text, query }
  }
})

app.component('SearchHighlight', {
  props: ['text', 'query'],
  
  setup(props, { slots }) {
    return () => {
      if (!props.query) {
        // Small optimization so we don't split a long string into
        // an array of individual characters
        return props.text
      }
      
      const re = RegExp(`(${escapeRegExp(props.query)})`, 'i')
      const parts = props.text.split(re)

      return parts.map((part, i) => {
        // Every odd element is the matched text
        return i % 2 === 0
          ? part
          : slots.default(part)
      })
    }
  },
})

app.mount('#app')
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>

<div id="app">
  <input type="search" v-model="query">
  <div>
    <search-highlight :text="text" :query="query" v-slot="highlight">
      <strong>{{ highlight }}</strong>
    </search-highlight>
  </div>
</div>
dgiusagp

dgiusagp3#

我找到了一个简单的解决方案。这可能不是最佳实践或安全。无论如何,我修改了boldText函数,类似于,

function boldText(text) {
  let newText = text.replace('<', '&lt;')
  newText = newText.replace('>', '&gt;')
  newText = newText.replace('/', '&#x2215;')
  // these three lines prevents browser from rendering html tags
  return newText.replace(new RegExp('(' + search.value + ')', 'gi'), '<b>$1</b>') // this ensures case-sensitivity and replace text in whole text instead of first match
}

相关问题