Reputation: 1013
I am have an array of items that will be fetched fom an API. First, I display the string replacing ###
with ______
. Then when I click the buttons I want to replace them with <span>word</span>
. so I'am using using v-html. I thought the new element would be shown but it doesn't. what would I have to do?
Code: https://jsfiddle.net/uosm30p9/
var example1 = new Vue({
el: '#example',
data: {
items: [{
str: 'This is ###.',
list: ['Frank', 'Eva']
},
{
str: 'I am not ###.',
list: ['George', 'John', 'Mark']
}
],
},
computed: {},
methods: {
createStr(item) {
item.newStr = item.str;
item.newStr = item.newStr.replace("###", "________")
return item.newStr
},
update(item, word) {
item.newStr = item.str;
var span = "<span class='.span1'>" + word + "</span>";
item.newStr = item.newStr.replace("###", span)
console.log(item.newStr);
}
}
});
.span1 {
color: blueviolet;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.min.js"></script>
<div id="example">
<ul>
<li v-for="(item,i) in items">
<span v-html="createStr(item)"></span>
<ul>
<li v-for="(word,j) in item.list">
<button v-on:click="update(item,word)">{{word}}</button>
</ul>
</li>
</ul>
</div>
Upvotes: 0
Views: 4602
Reputation: 5455
First try making your data object reactive so that alterations to the item array can be observed by Vue:
data: function () {
return {
items: [
{
str: 'This is ###.',
list: ['Frank', 'Eva']
},
{
str: 'I am not ###.',
list: ['George', 'John', 'Mark']
}
]
}
},
Look at the example at the bottom of this page: https://v2.vuejs.org/v2/guide/reactivity.html
Upvotes: 0
Reputation: 752
Ok, in order to solve your problem more easily and separating concerns, I came to a solution by setting up a template and storing the current value in each element "state".
HTML:
<div id="example">
<ul>
<li v-for="(item,i) in items">
<span v-html="createStr(item)"></span>
<ul>
<li v-for="(word,j) in item.list">
<button v-on:click="update(item, j)">{{word}}</button>
</ul>
</li>
</ul>
</div>
Javascript:
var example1 = new Vue({
el: '#example',
data: {
defaultReplacement: "_________",
items: [{
selectedOption: null,
template: 'This is <b class="span1">###</b>.',
list: ['Frank', 'Eva']
},
{
selectedOption: null,
template: 'I am not <b class="span2">###</b>.',
list: ['George', 'John', 'Mark']
}
],
},
computed: {},
methods: {
createStr(item) {
var listItem = (item.selectedOption != null) ? item.list[item.selectedOption] : this.defaultReplacement;
return item.template.replace("###", listItem);
},
update(item, j) {
item.selectedOption = j;
}
}
});
Here's the working example: https://jsfiddle.net/feload/rhnf8zv4/5/
Upvotes: 1
Reputation: 47
var example1 = new Vue({
el: '#example',
data: {
items: [{
str: 'This is ###.',
list: ['Frank', 'Eva'],
current: "________"
},
{
str: 'I am not ###.',
list: ['George', 'John', 'Mark'],
current: "________",
}
],
},
computed: {},
methods: {
createStr(item) {
item.newStr = item.str;
item.newStr = item.newStr.replace("###", item.current);
return item.newStr;
},
update(item, word, idx) {
item.current = word;
this.$set(this.items, idx, item);
}
}
});
.span1 {
color: blueviolet;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.min.js"></script>
<div id="example">
<ul>
<li v-for="(item,i) in items">
<span v-html="createStr(item)"></span>
<ul>
<li v-for="(word,j) in item.list">
<button v-on:click="update(item,word, i)">{{word}}</button>
</ul>
</li>
</ul>
</div>
Upvotes: 0