vue-highlight-words
A simple port from
react-highlight-wordsVue component to highlight words within a larger body of text.
Why?
It uses render to handle the highlighted text instead of using v-html or el.innerHtml.
Installation
npm i --save vue-highlight-words Usage
To use it, just provide it with an array of search terms and a body of text to highlight.
<template> <div id="app"> // attrs on component are applied to the wrapper `<span>` <Highlighter class="my-highlight" :style="{ color: 'red' }" highlightClassName="highlight" :searchWords="keywords" :autoEscape="true" :textToHighlight="text"/> </div> </template> <script> import Highlighter from 'vue-highlight-words' export default { name: 'app', components: { Highlighter }, data() { return { text: 'The dog is chasing the cat. Or perhaps they\'re just playing?', words: 'and or the' } }, computed: { keywords() { return this.words.split(' ') } } } </script>And the Highlighter will mark all occurrences of search terms within the text:
Props
| Property | Type | Required? | Description |
|---|---|---|---|
| activeClassName | String | The class name to be applied to an active match. Use along with activeIndex | |
| activeIndex | Number | Specify the match index that should be actively highlighted. Use along with activeClassName | |
| activeStyle | Object | The inline style to be applied to an active match. Use along with activeIndex | |
| autoEscape | Boolean | Escape characters in searchWords which are meaningful in regular expressions | |
| caseSensitive | Boolean | Search should be case sensitive; defaults to false | |
| findChunks | Function | Use a custom function to search for matching chunks. This makes it possible to use arbitrary logic when looking for matches. See the default findChunks function in highlight-words-core for signature. Have a look at the custom findChunks example on how to use it. | |
| highlightClassName | String | CSS class name applied to highlighted text | |
| highlightStyle | Object | Inline styles applied to highlighted text | |
| highlightTag | String | Component | Type of tag to wrap around highlighted matches; defaults to mark but can also be a component | |
| sanitize | Function | Process each search word and text to highlight before comparing (eg remove accents); signature (text: string): string | |
| searchWords | Array | ✓ | Array of search words. The search terms are treated as RegExps unless autoEscape is set. |
| textToHighlight | String | ✓ | Text to highlight matches in |
| unhighlightClassName | String | CSS class name applied to unhighlighted text | |
| unhighlightStyle | Object | Inline styles applied to unhighlighted text |
Custom highlight tag
You can custom the highlight tag by providing a compoent to the highlightTag prop. The component should have a <slot> for children, then either accept props:
| Props | Type | Description |
|---|---|---|
| highlightIndex | Number | Index of matched text |
For example:
<template> <div id="app"> // attrs on component are applied to the wrapper `<span>` <Highlighter class="my-highlight" :style="{ color: 'red' }" highlightClassName="highlight" + :highlightTag="tag" :searchWords="keywords" :autoEscape="true" :textToHighlight="text"/> </div> </template> <script> import Highlighter from 'vue-highlight-words' + const Highlight = { + template: '<strong><slot></slot> ({{ highlightIndex }}) </strong>', + props: ['highlightIndex'] + } export default { name: 'app', components: { Highlighter }, data() { return { text: 'The dog is chasing the cat. Or perhaps they\'re just playing?', words: 'and or the', + tag: Highlight } }, computed: { keywords() { return this.words.split(' ') } } } </script>or use scoped slot:
| Name | Description | DefaultContent |
|---|---|---|
| default | slot with prop highlightIndex and children | Matched text |
2.6.0+ scoped slot example:
<template> <div id="app"> // attrs on component are applied to the wrapper `<span>` <Highlighter class="my-highlight" :style="{ color: 'red' }" highlightClassName="highlight" + highlightTag="strong" :searchWords="keywords" :autoEscape="true" - :textToHighlight="text"/> + :textToHighlight="text" + v-slot="{ highlightIndex, children }"> + {{children}} ({{highlightIndex}}) + </Highlighter> </div> </template> <script> import Highlighter from 'vue-highlight-words' + const Highlight = { + template: '<strong><slot></slot></strong>', + } export default { name: 'app', components: { Highlighter }, data() { return { text: 'The dog is chasing the cat. Or perhaps they\'re just playing?', words: 'and or the', + tag: Highlight } }, computed: { keywords() { return this.words.split(' ') } } } </script>Deprecated slot-scope example:
<template> <div id="app"> // attrs on component are applied to the wrapper `<span>` <Highlighter class="my-highlight" :style="{ color: 'red' }" highlightClassName="highlight" + :highlightTag="tag" :searchWords="keywords" :autoEscape="true" - :textToHighlight="text"/> + :textToHighlight="text"> + <span slot-scope="{ highlightIndex, children }"> + {{children}} ({{highlightIndex}}) + </span> + </Highlighter> </div> </template> <script> import Highlighter from 'vue-highlight-words' + const Highlight = { + template: '<strong><slot></slot></strong>', + } export default { name: 'app', components: { Highlighter }, data() { return { text: 'The dog is chasing the cat. Or perhaps they\'re just playing?', words: 'and or the', + tag: Highlight } }, computed: { keywords() { return this.words.split(' ') } } } </script>Project setup
npm install Compiles and hot-reloads for development
npm run serve Compiles and minifies for production
npm run build Lints and fixes files
npm run lint License
MIT License - fork, modify and use however you want.
