Reputation: 135
I am trying to change the color of some hardcoded substrings that can be present in a v-for loop used to populate a table.
My loop is the following:
<tr v-for="(src, index) in contentArray.content" :key="src.id">
<td class="myclass1" >{{ src.something1 }}</td>
<td class="myclass2">{{ src.string }}</td>
</tr>
Let's say that I want to apply a specific color on a substring of src.string
.
For instance if src.string
is:
This is a test
I want to be able to apply a color on the word 'test'.
The substring that I want to color will not be present in every string of the loop.
I have a subset of multiple hardcoded substrings that I want to color.
How can I do that ?
I tried to play with another v-for loop with the split
method, or with a v-bind:class
but I can figure how to do this ...
Thanks
Upvotes: 0
Views: 411
Reputation: 138656
You could split the string in the template, and conditionally render a span
only for each matching word:
<template v-for="w in src.string.split(/\s+/)">
<span class="keyword" v-if="w === searchWord">{{w}} </span>
<template v-else>{{w}} </template>
</template>
Note this solution limits the searchability of phrases (it searches only for single words).
Alternatively, you could use a computed property that wraps only the target word(s) with a span
:
Declare a computed property (called "computedContent"
) that preprocesses the string
properties of contentArray.content
, wrapping all target words with <span class="keyword">
:
export default {
computed: {
computedContent() {
const searchWord = this.searchWord.trim()
if (!searchWord) return this.contentArray.content
return this.contentArray.content.map(x => ({
...x,
string: x.string.replace(new RegExp(searchWord, 'ig'), w => `<span class="keyword">${w}</span>`)
}))
}
}
}
Update the template to use this computed property instead:
<tr v-for="(src, index) in computedContent" :key="src.id">
Use the v-html
directive to bind the td
's innerHTML
to src.string
:
<td class="myclass2" v-html="src.string"></td>
In your component's <style>
block, select .keyword
to style it:
<style>
.keyword {
font-family: Monaco, sans-serif;
font-weight: bold;
color: blue;
}
</style>
Upvotes: 1
Reputation: 199
<tr v-for="(src, index) in contentArray.content" :key="src.id">
<td class="myclass1" >{{ src.something1 }}</td>
<td class="myclass2">
{{ src.string.includes('test') ? src.string.replace('test', `${<span :class={color: 'yourColor'}></span>}`) : src.string }}
</td>
</tr>
You can check for the word you want to change with .includes() and replace that word with .replace() with the html tag and class you want
Upvotes: 1
Reputation: 1
You could split the string as you said then bind the class conditionally :
<td class="myclass2">
<span v-for="substr in src.string.split(' ')" :class="{'someClass':substr==='test'}">
{{substr}}
</span>
</td>
Upvotes: 0