如何在Vue模板中定义变量?

13

问题

我需要在Vue模板中暂时存储方法调用的结果。这在循环内部特别常见,因为我无法轻松地使用计算属性。

<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片段:

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

    return options;
}
为了提高性能,我真的需要一个变量来存储方法调用结果。在Vue中,如何解决这个问题?
8个回答

18

通过 v-for 和单个循环使用作用域是解决 Vue 当前不足的快速方法。以下是一个希望能够解释清楚的例子:

<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>

上面的<template>元素就是关键。你可以在一个临时大小为1的对象数组中调用你的函数(someFunction),将其分配给一个属性(isLocked),然后再分配给一个作用域变量(scope)。现在你可以通过scope.isLocked无限次访问一些函数返回的任何内容,而不会牺牲性能。


6

在模板的任何位置,您都可以使用:set="VAART = 12"来篡改您的代码,神奇地,VAART变量将被设置(但不会是响应式的)

我已在VUE 3上测试过这个魔术技巧


3

你可以创建一个计算属性,将类型对象合并到vehiclesTypes数组中。

computed: {

  vehicles() {
    return this.vehicleTypes.map(vehicle => {
       return {
         value: vehicle,
         type: { ...this.getVehicleTypeData(vehicle) }
       }
    })
  }

},

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

    return options;
  }
}

您可以做到:

<ul>
  <li v-for="vehicle of vehicles" :key="vehicle.value">
    <h3>{{ vehicle.value }}</h3>
    <div v-if="vehicle.type">
     {{ vehicle.type.costPerMile }}<br>
     {{ vehicle.type.costPerHour }}<br>
    </div>
  </li>
</ul>

如果您按照逻辑操作,我相信它会起作用。但是我不知道vehiclesTypes的值,所以上面的代码可能需要一些更改。

希望能对您有所帮助。


2

一种选择是定义一个组件。你可以将需要“存储”的值作为prop传递给它,并且它可以多次使用。这是更Vue风格的方法。

另一个选择是将函数调用包装在数组中,并使用v-for为其创建别名。这更像是一种hacky/lazy的优化,但它并不脆弱,只是阅读起来有些奇怪。

最初的回答:

一种选项是定义一个组件。您可以将需要“存储”的值作为prop传递给它,并且它可以多次使用。这是更符合Vue风格的方法。

另一种选择是将函数调用包装在数组中,并使用v-for为其创建别名。这更像是一种hacky/lazy的优化,但它并不脆弱,只是阅读起来有些奇怪。

new Vue({
  el: '#app',
  data: {
    vehicleTypes: [0, 1]
  },
  methods: {
    getVehicleTypeData(type) {
      return [{
        costPerMile: 10,
        costPerHour: 40
      }][type];
    }
  }
});
<script src="https://unpkg.com/vue@latest/dist/vue.js"></script>
<ul id="app" new>
  <li v-for="vehicleType in vehicleTypes" :key="vehicleType">
    <h3>{{ vehicleType }}</h3>
    <template v-for="data in [getVehicleTypeData(vehicleType)]">
      <div v-if="data">
       {{ data.costPerMile }}<br> {{ data.costPerHour }}<br>
      </div>
    </template>
  </li>
</ul>


2
最初的回答: 我通过一些研究找到了一个解决方案,并发布了自己的答案,但不确定是否有其他更好的解决方案。
Javascript代码片段:
const Pass = {
  render() {
    return this.$scopedSlots.default(this.$attrs)
  }
}

export default {
  components: {
    Pass
  },
  data: function () {
    return {
      vehicleTypeOptions: [],
    }
  },
  methods: {
    getVehicleData: function(vehicleType){
      let option = _.find(this.vehicleTypeOptions, (obj)=>{
        return obj.vehicleType==vehicleType;
      });
      return option;
    },
    loadData: function(){
      // get data from server using API and set to vehicleTypeOptions
    }
  },
  mounted: function(){
    this.loadData();
  }
}

模板片段:

<Pass v-for="vehicleType in VehicleTypes" v-bind:key="vehicleType" :temp="getVehicleData(vehicleType)">
  <div slot-scope="{temp}">
    <div class="pannel">
        <h6>{{ vehicleType }}</h6>
        <p v-if="temp">
          Cost per mile: <strong>${{ temp.costPerMile }}</strong>, 
          Cost per hour: <strong>${{ temp.costPerHour }}</strong>, 
          Cost per day: <strong>${{ temp.costPerDay }}</strong>
        </p>
    </div>
  </div>
</Pass>

1
这种方法也使用了作用域插槽,但更加简洁:https://dev.to/loilo/an-approach-to-vuejs-template-variables-5aik - thet

1

1
很遗憾,在当前版本中无法实现 :(
在您的示例中,您可以使用计算值创建计算,并使用它。
<ul>
  <li v-for="vehicleType, idx in vehicleTypes" :key="vehicleType">
    <h3>{{ vehicleType }}</h3>
    <div v-if="vtData[idx]">
     {{ vtData[idx].costPerMile }}<br>
     {{ vtData[idx].costPerHour }}<br>
    </div>
  </li>
</ul>

...

computed: {
  vtData() {
    return this.vehicleTypes.map(vt => this.getVehicleTypeData(vt));
  }
}

0
据推测,这应该是一个可靠的策略:
<template>
  <div :style="{ opacity: 0, position: 'absolute' }">{{ variable = -Infinity }}</div>
  {{ variable }}
</template>

<script>
export default {
  mounted () {
    // The variable is actually added to the component.
    console.log (this.variable)
  }
}
</script>

在模板循环中也有一种定义变量的方法。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接