panthro
panthro

Reputation: 24061

v-model concatenate a string with a var?

I've read answers such as this, but I can't get my template to compile.

I need to concatenate a string with a variable in v-model to bind to an array inside an object:

<li v-for="name in names">
    <input type="checkbox" v-model="'checked.'+name">
    ....

I just get a compile error though.

Also when I do this:

:data-test="'checked.'+name"

It compiles fine, so it's something with v-model.

The compile error is:

Syntax Error: SyntaxError: Unexpected token (1:1161)

Upvotes: 2

Views: 7666

Answers (3)

Cloud Soh Jun Fu
Cloud Soh Jun Fu

Reputation: 1502

The v-model="name" helps you do two things.

  1. :value="name"
  2. @input="name = $event

However, in your case, you're doing v-model="'checked.'+name", which means:

  1. :value="'checked.'+name" // Which is perfectly fine
  2. @input="'checked.'+name = $event" // This would cause an error.

Documentation can be found here.

Below is some solution of mine: JsFiddle

  computed: {
    checkedName: {
      // getter
      get: function () {
        return `${this.prefix}${this.name}`;
      },
      // setter
      set: function (newValue) {
        this.name = newValue.replace(this.prefix, '');
      }
    }
  },

then

<input type="checkbox" v-model="checkedName">

Upvotes: 1

Stephen Thomas
Stephen Thomas

Reputation: 14053

Just in case a slightly different perspective helps: Whether you use it in a v-model or :data-test directive

'checked.'+name

results in a string. Although it probably isn't what one would normally want to do, that is syntactically legal for an arbitrary v-bind (e.g. :data-test). That is not, however, syntactically legal for a v-model. As other have pointed out, v-model attempts to assign a value on "change" events. It would be equivalent, for example, to

'checked.foo' = true;

when what I think you want is

checked.foo = true;

It's hard to say for sure without seeing more of your code, but it may be the case that

<input type="checkbox" v-model="checked[name]">

is sufficient for you.

Upvotes: 3

Nino Filiu
Nino Filiu

Reputation: 18473

You can't do that.

v-model is used for two-way data binding and is a syntactic sugar for :checked="myField" + @change="evt => myField = evt.target.checked in the case of a checkbox.

As you can see, myField must be a valid left-hand side expression in JS, this is by the way one of the rules precised by Vue to have a valid v-model:

The directive does not have the attribute value which is valid as LHS. E.g. <input v-model="foo() + bar()">

And that is exactly why your template doesn't compile. Vue can understand how to bind the data in one way because it can assign 'checked.'+name to a variable, but it can't assign a variable to 'checked.'+name - that is not a valid left-hand sign expression.

Upvotes: 0

Related Questions