I have strings that contains ###
and I am replacing with array values. Now I want to use them with a component, I created the component and it works but I don't know how to use it in the strings. I don't want to wrap them manually because I don't know how the strings will be, it can have several ###
. If it has 2 ###
, options will have 2 subArrays.
What is the better way to do it?
Code: https://jsfiddle.net/tsobh4nu/
Vue.component('opt', {
template: `<label>
<span class="bold" v-for="(str,idx) in options">
{{str + " / "}}
</span>
</label>`,
props:{options: Array}
})
new Vue({
el: '#app',
data: {
str: "I have ### and you have a ###.",
options: [
['AAA', 'BBB', 'CCC'],
['XXX', 'YYY', 'ZZZ']
]
},
computed:{
replacedStr(){
let newStr = this.str;
this.options.forEach(option=>{
newStr = newStr.replace('###',this.concatenateOptions(option));
})
return newStr;
}
},
methods: {
concatenateOptions(strArr) {
let separator = "";
let strOptions = "";
strArr.forEach(word => {
strOptions += separator + word;
separator = " / ";
});
return strOptions;
}
}
})
.bold {
font-weight: bold
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.min.js"></script>
<div id="app">
<p>I want something like this, but using components: </p>
{{replacedStr}}
<br>
<hr>
My Components:<br>
<opt :options="options[0]"></opt>
<br>
<opt :options="options[1]"></opt>
</div>
Many thanks.
This is more general, but I hope it will help someone. Add a dynamic component in your template:
<component v-bind:is="processedHtml"></component>
.Then add a computed method:
Where
<my-component>
is your custom component and thethis.html
is your HTML content that contains the placeholder[Placeholder]
.It is important to return an element that has one root node. That's why the return is wrapped with
<div>
.Read more advanced tutorial about this issue here in my blog. For example, to pass props to
<my-component>
You need to move up the food chain ! You're going to lengths to bypass the goodness of vue. Your
data.string
is a template, and your ### is a not very meaningful placeholder, and then you have to do the work yourself.Can't you use Vue's templating system? And your concatenateOptions method can be replaced with Array.join().