Как определить переменную в шаблоне Vue? - PullRequest
0 голосов
/ 30 января 2019

Проблема

У меня есть необходимость временно сохранить результаты вызова метода в шаблонах 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 способ решить эту проблему?

Ответы [ 5 ]

0 голосов
/ 18 июня 2019

Быстрый способ обойти текущие недостатки Vue - это использовать область видимости через v-for и один цикл.Надеемся, что пояснительный пример:

<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> выше делает свое дело.Вы вызываете свою функцию (someFunction) во временном массиве объектов размера 1, назначаете его свойству (isLocked), которое, в свою очередь, присваивается переменной области действия (scope).Теперь вы можете получать доступ ко всем функциям someFunction столько раз, сколько захотите, не жертвуя производительностью через scope.isLocked.

0 голосов
/ 30 января 2019

Вы можете просто создать вычисляемое свойство, которое объединит тип obj с массивом 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>

Если вы следуете логике, яуверен, что это будет работать.Хотя я не знаю значений стандартных типов транспортных средств, поэтому приведенный выше код может потребовать некоторых изменений.

Надеюсь, это поможет вам.

0 голосов
/ 30 января 2019

Один из вариантов - определить компонент.Вы можете передать значение, которое вам нужно «сохранить», в качестве реквизита, и он может использовать его несколькими способами.Это более гибкий подход.

Другой вариант - заключить вызов функции в массив и использовать v-for, чтобы создать для него псевдоним.Это скорее хакерская / ленивая оптимизация, но она не хрупкая, просто странная для чтения.

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>
0 голосов
/ 30 января 2019

Я нашел решение по результатам некоторых исследований, и я отправляю ответ сам, но не уверен, есть ли другие лучшие решения.

Фрагмент 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>
0 голосов
/ 30 января 2019

К сожалению, это невозможно в текущей версии: (

В вашем примере вы можете сделать вычисленные с вычисленными значениями и использовать его.

<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));
  }
}
...