使用Vue.js突出显示Elasticsearch的搜索结果

时间:2019-02-04 23:37:25

标签: elasticsearch vue.js

我正在尝试使用Elasticsearch后端和Vue.js前端构建搜索引擎。它主要基于此tutorial。有人建议,一个不错的功能是突出显示带有初始搜索词的搜索结果,即如果我在搜索栏中搜索“ foo”,那么搜索结果将类似于 foo bar。

我尝试将v-html块放入各个div中,但通常没有成功。

我的弹性索引记录与此格式匹配:

result._source.Title,
result._source.description, 
result._source.contact, 
result._source.contactEmail

HTML:

 <div class="row">
    <div class="col-md-6" v-for="result in results" v-html="highlight(result._source.Title)">
        <div class="ul">
            <ul>
                <li>{{ result._source.Title }},</li>
                <li>{{ result._source.description  }},</li>
                <li>{{ result._source.contact }},</li>
                <li>{{ result._source.contactEmail }} </li>

JS:高亮显示功能

        highlight(text) {
            return text.replace(new RegExp(this.query, 'gi'), '<span class="highlight">$&</span>')
        }
}

我已经能够实现基本功能来突出显示单个数据点,但是页面的其余部分无法呈现。例如,在此示例中,标题将突出显示,但描述,联系人和contactEmail将不会呈现在页面上。此外,如果搜索词与标题不匹配,则页面会出错。

1 个答案:

答案 0 :(得分:0)

这可能是由于您的v-html指令:highlight(result._source.Title)中的函数调用所致。

相反,您应该使用v-html绑定到每个结果属性,这使您可以在更新模板之前替换任何属性中的出现。

尝试更新与以下代码类似的代码:

new Vue({
  el: '#app',
  data() {
    return {
      content: [{
          title: 'Result 1',
          text: `Phasellus euismod neque diam, aliquam commodo neque venenatis in. Sed non eros lorem. Fusce sit amet gravida nunc. Nunc non pulvinar tellus. Donec rutrum sagittis nulla eu commodo. Morbi condimentum molestie tortor venenatis dignissim. Aenean ac ligula at lectus pharetra sagittis. Integer convallis ipsum ex, ut congue urna auctor in. Sed consequat elit ipsum, eu vestibulum nisl egestas sit amet. Aenean eu mi et metus congue porttitor ut vitae augue. Donec congue semper euismod. Nam eget turpis eros. In vitae viverra eros.`
        },
        {
          title: 'Result 2',
          text: `Nunc vehicula lorem a enim pharetra pellentesque. Nullam nulla nisi, imperdiet at blandit in, molestie sed ipsum. Curabitur elit nisl, aliquam vel urna at, tincidunt interdum tortor. Sed lacinia urna non tellus consectetur molestie. Cras nunc justo, suscipit eu luctus eget, viverra at nisl. Curabitur ut sodales justo, sit amet varius arcu. Nulla non varius justo, ut mattis diam. Nam venenatis malesuada enim. Ut id convallis augue. Pellentesque pretium aliquam porttitor. Donec at velit pulvinar, consequat eros at, ultrices urna. Sed non nisl tellus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nullam dictum ipsum dolor, vitae volutpat dolor porta non.`
        },
        {
          title: 'Result 3',
          text: `Morbi bibendum justo enim, aliquam placerat magna euismod in. Sed ullamcorper augue ac nisl efficitur, eget ullamcorper neque rhoncus. Duis ac tristique orci. Curabitur lorem purus, varius eu sodales non, feugiat auctor orci. Pellentesque feugiat, felis eu accumsan ornare, lacus metus ultrices ipsum, vitae consequat velit neque in sapien. Nunc fringilla sollicitudin hendrerit. Vestibulum at massa convallis, finibus lacus ac, venenatis nulla. Nulla in condimentum metus. Donec sagittis nulla sed elit semper tristique. Vivamus facilisis sed lectus sed semper.`
        },
        {
          title: 'Result 4',
          text: `Phasellus suscipit eros ex, sed auctor turpis accumsan non. In ultrices convallis sem id tempor. Sed elementum ac lectus et scelerisque. Mauris vel leo a sem elementum volutpat. Vestibulum congue urna id velit porta, id scelerisque nulla pulvinar. Aliquam sit amet iaculis enim. Vestibulum enim tortor, sodales ut pharetra semper, eleifend sed lectus. Phasellus fringilla leo vel turpis feugiat lacinia. Morbi neque dui, vulputate eget molestie non, hendrerit eu felis. Phasellus erat erat, tempus ut mi ut, maximus dapibus nulla. Phasellus dignissim sollicitudin velit sit amet rhoncus. Curabitur commodo magna eget ex consequat, eget sollicitudin metus rhoncus. Aenean enim libero, dictum nec tempus quis, molestie at nulla.`
        },
        {
          title: 'Result 5',
          text: `Mauris ullamcorper mauris nec justo sodales, ac facilisis ipsum fringilla. Nam at urna eu ante luctus dignissim. In sit amet magna aliquam nibh tincidunt luctus vitae at arcu. Proin eu cursus tortor. Proin porttitor erat ac tortor ullamcorper lacinia. Curabitur sit amet ullamcorper ligula, rhoncus euismod est. Praesent non quam fermentum, bibendum lectus vel, auctor enim. Fusce eu viverra lectus. In molestie sit amet velit bibendum accumsan. Donec venenatis, urna sed convallis gravida, est est luctus mi, quis maximus ipsum metus sit amet ex. Vestibulum et nisi eu enim faucibus fermentum. Pellentesque pellentesque ultrices risus vel rutrum. Curabitur hendrerit urna in leo finibus rutrum. Maecenas posuere ultricies lectus eget elementum. Sed lacinia efficitur nisl, ac gravida urna ullamcorper consectetur. Aliquam erat volutpat.`
        }
      ],
      search: null
    }
  },
  computed: {
    blocks() {
      if (this.search) {
        const regex = new RegExp(this.search, 'g')

        return this.content.map(c => {
          return {
            title: c.title.replace(regex, `<span class="highlight">${this.search}</span>`),
            text: c.text.replace(regex, `<span class="highlight">${this.search}</span>`)
          }
        })
      }

      return this.content
    }
  }
})
.highlight {
  background-color: yellow;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <input type="text" v-model="search">

  <ul>
    <li v-for="(block,i) in blocks" :key="i">
      <p>Title: <span v-html="block.title"></span></p>
      <p>Text: <span v-html="block.text"></span></p>
    </li>
  </ul>
</div>