Paul Bastowski
Paul Bastowski

Reputation: 1176

Vue.js local template variables

I have a needed to create a local variable in my Vue template to shorten references to an otherwise long object $v.form.text, as shown in the example below:

<input 
    :class="{ error: !$v.form.text.required }"
    v-model.trim="$v.form.text.$model" 
/>

I would like to be able to access the $v.form.text nested object in my template as simply text.

<input 
    :class="{ error: !text.required }"
    v-model.trim="text.$model" 
/>

There is usually a lot more code than in the example above, justifying creating a temporary variable, but the problem is the same as shown.

Note: I have already solved this, please see answer below, and simply want to document the solution for others who might be searching for the same.

Upvotes: 7

Views: 6898

Answers (2)

LMK
LMK

Reputation: 1551

I just had this same problem and thought of another hack/workaround... Note I haven't tried this yet but should work.

Just use v-for with a single inline array containing your long expression, i.e.

<span v-for="item in [my.big.long.expression.item]">{{item.foo}} {{item.bar}}</span>

:)

Upvotes: 7

Paul Bastowski
Paul Bastowski

Reputation: 1176

I could of course just use a computed function to do this, but in some cases it is not possible, such as when you're inside a v-for and want your computed to refer to the loop's iterator variable. In such cases, my solution is as follows:

<div :set="text=$v.form.text">
    <input 
        :class="{ error: !text.required }"
        v-model.trim="text.$model" 
    />
</div>

For those that may now be thinking, "Hey, I didn't know there was an undocumented :set in Vue", there isn't.

What I'm doing here is relying on the fact that Vue will evaluate the JavaScript of any bound attributes and I just chose to invent an unused attribute called :set.

As a reminder, a bound attribute is one that is prefixed with a : or v-bind:. The JavaScript expression inside the double quotes will be evaluated in the context of the current component and the item variable will still be available outside of the v-for in which it is being set. So, it's not a local variable, as such, rather, it's a locally assigned, component scope variable.

Make sure to add this variable to your variable declarations in the data hook.

data() { return { 
    text: '' 
}}

Here is a link to a CodePen showing this pattern at work https://codepen.io/pbastowski/pen/PXqjPG?editors=1100

Upvotes: 6

Related Questions