0

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>

1
  • Are you sure you're updating the items array correctly? (See the caveats.) If Vue doesn't know that the array has been updated, it won't know that the old value from createStr() has become invalid. Commented Nov 10, 2018 at 1:35

3 Answers 3

1

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/

Sign up to request clarification or add additional context in comments.

Comments

0

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>

1 Comment

thanks, but I'd like a solution without having to add the current property
0

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.