Samuele B.
Samuele B.

Reputation: 658

Conditionally set v-model in Vue

I have a series of inputs that could be either checkboxes or radio buttons, depending on a value in the data of my vue component.

In particular, I have a Question component, and questions may accept only one answer or multiple answers. I have a selected_answers array in my data, and I was thinking I could have the checkboxes target it as their v-model, while the radio buttons could target selected_answers[0]. This way, I don't have to copy-paste che input elements and just change their type and v-model.

So, my solution would look something like this:

<input
    :type="question.accepts_multiple answers ? 'checkbox' : 'radio'"
    :id="'ans-' + answer.id"
    :value="answer.id"
    v-model="question.accepts_multiple_answers ? selected_answers : selected_answers[0]"
/>

However, eslint complains about my code:

'v-model' directives require the attribute value which is valid as LHS

What's a way I can accomplish what I'm trying to do?

Upvotes: 5

Views: 3795

Answers (3)

kissu
kissu

Reputation: 46676

You cannot use any advanced code inside of v-model (just a basic string), you could export question.accepts_multiple_answers ? selected_answers : selected_answers[0] to a computed and plug the computed to the v-model.

If you need to have a setter, you will need to write a computed setter, this looks like this

computed: {
  fullName: {
    // getter
    get() {
      return this.firstName + ' ' + this.lastName
    },
    // setter
    set(newValue) {
      var names = newValue.split(' ')
      this.firstName = names[0]
      this.lastName = names[names.length - 1]
    }
  }
}

Meanwhile, since v-model is just some sugar syntax, you could also replace it with usual :value + @input (depending of the type of the field). I do prefer to use those 2 than v-model nowadays, especially for the kind of limitations that you do have right now.

Upvotes: 4

Samuele B.
Samuele B.

Reputation: 658

Ended up figuring it out by myself.

<input
    :type="question.accepts_multiple_answers ? 'checkbox' : 'radio'"
    :id="'ans-' + answer.id"
    :value="question.accepts_multiple_answers ? answer.id : [answer.id]"
    v-model="selected_answers"
/>

Upvotes: 1

Robert Seghedi
Robert Seghedi

Reputation: 11

You can't really do it like that.

I recommend you to set up a variable when loading your component like that:

data()
{
    return {
        model_string: '',
    }
}

Then you give your variable some values depending on your own conditions

created() {
   if (your.first.condition) {
    this.model_string = your.value;
   } else if (your.other.condition) {
    this.model_string = your.value;
   }
}

After this, you can use it in your view as you wish

<input v-model="model_string" ..... // your attributes>

Upvotes: 1

Related Questions