javascriptvue.jsuser-interfacefrontendv-for

Creating Dummy Variables in v-for Loops


I am using Vue-JS and am running into an issue with v-for loops and v-model properties.

I have a list of items

<input
  v-for="i in list"
  v-model="i.model"
  ... (other tags that use i)
>
</input>

And some corresponding JavaScript

let model_thing = ref();

let list = [
  { model: ref(), data: "Whatever things" }
  { model: model_thing, data: "..." }, //I also tried something like this, where ref() is created outside of the list
]

But the issue is that the v-model simply doesn't work. I'm pretty sure this is due to the reference variable being in an array.

I think I have a way to solve this; it is a bit of a bad solution but a solution nonetheless. I don't really need the v-model after the page has loaded (and for Vue to actually know what the input should have inside it).

So what if I could create a "dummy" variable inside the v-for loop?

<input
  v-for="i in list"
  v-model="let dummy = ref(); /* use 'dummy' as the ref"
  ... (whatever else)
>
</input>

The UI framework I'm using is also a bit undocumented (Known as Maz-UI), so I can't just pull a solution like this:

<!-- I am using select dropdowns instead of inputs like before -->
<MazSelect
  v-for="i in list"
  :value="i.model"
  @input="i.model = $event.target.value"
>
</MazSelect>

As this is just giving me [object, Object] and the placeholder text is still showing.

Can someone tell me how to create dummy variables like this?


Solution

  • As mentioned in the comments, there's nothing wrong with how you use v-model. So my guess is that it'd work when wrapped inside a reactive:

    let model_thing = ref();
    
    let list = reactive([
      { model: ref(), data: "Whatever things" }
      { model: model_thing, data: "..." }, //I also tried something like this, where ref() is created outside of the list
    ])
    

    Note that due to how reactive works, you can also get rid of intermediary refs:

    let list = reactive([
      { model: undefined, data: "Whatever things" }
      { model: undefined, data: "..." }, //I also tried something like this, where ref() is created outside of the list
    ])
    

    Creating a temporary variable is usually a bad idea. Why? It's not reactive, meaning that only one part of the v-model would be useful: the binding part.

    That said, the way you envisioned it is also impossible since Vue's JS compiler for binds only allows expressions (and not statements).

    You can use literals, function calls, etc. but you can't create a proper variable, so to speak.

    For these 2 reasons, I don't think you can create refs on the fly. And as pointed out, when you reach such complex cases it's usually a sign that you need to refactor or subdivide.

    Your issue does raise an interesting issue in data modelling: vertical (multiple arrays) vs horizontal grouping (one array of objects).