I've got a string like this:
"Hello World! It's me, Chelsea."
And a list of strings.
["Hello", "World", "Chelsea"]
I'd like to dynamically wrap the matching strings in Vue components. Individually, it looks like this:
<MyComponent :text="Hello"/> <MyComponent :text="World"/>! It's me, <MyComponent :text="Chelsea"/>.
The solution for this could be something like the following (thanks Ulysse BN):
<template v-for="s in string.split(/\b/)">
<MyComponent v-if="list.includes(s)" :string="s"/>
<span v-else>{{ s }}</span>
</template>
But we run into problems where we have multi-word strings in our list (e.g. "It's me") and more specifically, overlapping words. If we added to the list of strings "Hello World", here's what the ideal result looks like:
<MyComponent :text="Hello World">
<MyComponent :text="Hello"/>
<MyComponent :text="World"/>!
</MyComponent>
It's me, <MyComponent :text="Chelsea"/>.
How can I achieve this functionality? I have a hunch it involves v-for and some kind of recursive function, but how I can't say.
I'm not sure of your use case, but maybe something like this would be suitable:
<template v-for="item in myContent">
<span v-if="item.type === 'string'">{{ item.content }}</span>
<my-component v-else-if="item.type === 'component'" :text="item.content" />
</template>
myContent: [
{'content': 'hello', type: 'string'},
{'content': 'hello world', type: 'component'},
{'content: 'world', type: 'component'},
{'content': 'oh hello world', type: 'string'}
]
You use computed to take the string and return it in this structure, breaking out any of the matched words.