Search code examples
javascriptvue.jsvue-component

How to define variable in vue template?


Problem

I have the need to temporarily store the results of a method call in Vue templates. This is particularly common inside loops, where I cannot easily use computed properties.

<ul>
  <li v-for="vehicleType in vehicleTypes" :key="vehicleType">
    <h3>{{ vehicleType }}</h3>
    <div v-if="getVehicleTypeData(vehicleType)">
     {{ getVehicleTypeData(vehicleType).costPerMile }}<br>
     {{ getVehicleTypeData(vehicleType).costPerHour }}<br>
    </div>
  </li>
</ul>

Javascript snippet:

getVehicleTypeData: function(vehicleType){
    let options = _.find(this.vehicleTypeOptions, (obj)=>{
      return obj.vehicleType==vehicleType;
    });

    return options;
}

To improve performance, I really need a variable to store the method call result.

What is the Vue way to solve this problem?


Solution

  • A quick way to work around Vue's current shortcomings is to use scoping through v-for and a single loop. A hopefully explanatory example:

    <v-list>
      <v-list-tile v-for="(module, idx) in modules">
        <template v-for="scope in [{ isLocked: someFunction(module)}]">
          <!-- any markup -->
          <v-list-tile-action v-if="scope.isLocked">
            <v-icon color="amber">lock</v-icon>
          </v-list-tile-action>
        </template>
      </v-list-tile>
    </v-list>
    

    The <template> element above does the trick. You call your function (someFunction) in a temporary size-1 array of objects, assign it to a property (isLocked), which in turn is assigned to a scoped variable (scope). You can now access whatever someFunction returns as many times as you like without sacrificing performance through scope.isLocked.