简体   繁体   English

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

[英]Highlight Search Results from Elasticsearch using Vue.js

I am attempting to build a search engine with an Elasticsearch backend and a Vue.js front end.我正在尝试使用 Elasticsearch 后端和 Vue.js 前端构建一个搜索引擎。 It is primarily based upon this tutorial .它主要基于本教程 It was suggested that a nice feature would be to highlight search results with the initial search term ie if I search "foo" in the search bar, then a search result would look something like foo bar.有人建议,一个不错的功能是用初始搜索词突出显示搜索结果,即如果我在搜索栏中搜索“foo”,那么搜索结果将看起来像foo bar。

I have tried placing the v-html block into various divs, but usually to no success.我曾尝试将 v-html 块放入各种 div 中,但通常没有成功。

My elastic index records that match this format:我的弹性索引记录符合这种格式:

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

HTML: 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 function JS:高亮功能

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

I have been able to implement basic functionality to highlight a single data point, but the rest of the page does not render.我已经能够实现基本功能来突出显示单个数据点,但页面的其余部分不会呈现。 For instance, in this example, title will be highlighted, but the description, contact, and contactEmail will not render on the page.例如,在此示例中,标题将突出显示,但描述、联系人和联系人电子邮件不会在页面上呈现。 Additionally, if the search term does not match the title, the page errors out.此外,如果搜索词与标题不匹配,页面就会出错。

It's likely due to to the function call in your v-html directive: highlight(result._source.Title) .这可能是由于您的v-html指令中的函数调用: highlight(result._source.Title)

Instead you should be using v-html to bind to each result property, which allows you to replace occurrences in any of the properties before updating the template.相反,您应该使用v-html绑定到每个结果属性,这允许您在更新模板之前替换任何属性中的匹配项。

Try updating your code similar to the following:尝试更新类似于以下内容的代码:

 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>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM