yariv bar
yariv bar

Reputation: 976

VueJS dynamic v-model value

I want to set v-model to a value dictated by the value in my v-for loop. here's my code:

<tr v-for="campaign in _campaigns">
    <el-switch v-model="campaign.enabled"></el-switch>
</tr>

now if campaign.enabled === 'active' i want to set v-model to on , or if
campaign.enabled === 'inactive' than off.

i tried to add logic to v-model in few ways like: v-model="campaign.enabled === 'active' ? on : off" or to use a method but none worked. Any idea what will consider as best practice to achieve that?

Upvotes: 1

Views: 6050

Answers (3)

reinerBa
reinerBa

Reputation: 1660

The directive v-model is limited to the input types

  • <input>
  • <select>
  • <textarea>
  • and vue components

https://v2.vuejs.org/v2/api/#v-model

So a bool value will work for <input type="radio" ...> and type="checkbox" you cannot set

set v-model to on

you can only set an input to checked or unchecked. If you want to disable or hide the component use v-if or v-show.

You are trying to use v-model on a component, so you should read this https://v2.vuejs.org/v2/guide/components.html#Form-Input-Components-using-Custom-Events or https://v2.vuejs.org/v2/guide/forms.html#v-model-with-Components . In most cases i think using props in the component would be the better solution. Because v-model is the standard two way binding directive.

Upvotes: 0

Roy J
Roy J

Reputation: 43881

v-model needs to be able to assign to its argument as well as read its value. The values it expects to receive and assign are booleans. Since you want to convert those to strings you will need to have methods to encode and convert the values, and you will need to separate the v-model into its component value and on:input bindings.

new Vue({
  el: '#app',
  data: {
    campaigns: [{
      enabled: 'active'
    }]
  },
  methods: {
    decodeCampaign(c) {
      return c.enabled === 'active';
    },
    encodeCampaign(b) {
      return b ? 'active' : 'inactive';
    }
  }
});
<script src="//cdnjs.cloudflare.com/ajax/libs/vue/2.3.4/vue.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/element-ui/1.4.0/index.js"></script>
<link href="//cdnjs.cloudflare.com/ajax/libs/element-ui/1.4.0/theme-default/index.css" rel="stylesheet" />
<div id="app">
  <div v-for="campaign in campaigns">
    <el-switch :value="decodeCampaign(campaign)" @input="(v) => campaign.enabled = encodeCampaign(v)"></el-switch>
    {{campaign.enabled}}
  </div>
</div>

If you didn't have an array, you could use the encode and decode to implement a settable computed, and use v-model with it, but there's no good way to make a computed for each element of your array.

Upvotes: 3

V. Sambor
V. Sambor

Reputation: 13389

Try this:

<tr v-for="campaign in _campaigns">
    <el-switch v-model="campaign.enabled === 'active'"></el-switch>
</tr>

docs says you have to provide an boolean to the v-model: http://element.eleme.io/#/en-US/component/switch1

Upvotes: 0

Related Questions