eag845
eag845

Reputation: 1013

how to update a value in v-html Vue

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

Answers (3)

Marc
Marc

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

Felipe
Felipe

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

honglin xiao
honglin xiao

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

Related Questions