Выделите результаты поиска из Elasticsearch с помощью Vue.js - PullRequest
0 голосов
/ 05 февраля 2019

Я пытаюсь создать поисковую систему с бэкэндом Elasticsearch и интерфейсом Vue.js.Это в первую очередь основано на этом учебнике .Было высказано предположение, что хорошей функцией будет выделение результатов поиска начальным поисковым термином, т.е. если я буду искать «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 голосов
/ 05 февраля 2019

Вероятно, это связано с вызовом функции в вашей директиве 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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...