【问题标题】:How to define variable in vue template?如何在 vue 模板中定义变量?
【发布时间】:2019-06-24 01:25:59
【问题描述】:

问题

我需要将方法调用的结果临时存储在 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 sn-p:

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

    return options;
}

为了提高性能,我确实需要一个变量来存储方法调用结果。

Vue解决这个问题的方法是什么?

【问题讨论】:

    标签: javascript vue.js vue-component


    【解决方案1】:

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

    上面的&lt;template&gt; 元素可以解决问题。您在一个临时大小为 1 的对象数组中调用您的函数 (someFunction),将其分配给一个属性 (isLocked),然后将其分配给一个作用域变量 (scope)。现在,您可以通过scope.isLocked 访问任意次数的 someFunction 返回的任何内容,而不会牺牲性能。

    【讨论】:

      【解决方案2】:

      您可以创建一个计算属性,将类型 obj 合并到车辆类型数组中。

      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>
      

      如果您遵循逻辑,我相信它会起作用。虽然我不知道车辆类型的值,但它上面的代码可能需要一些更改。

      希望对你有帮助。

      【讨论】:

        【解决方案3】:

        一个选项是定义一个组件。您可以将需要“存储”的值作为道具传递给它,并且可以多种方式使用它。这是更接近 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>

        【讨论】:

          【解决方案4】:

          我从一些研究中找到了解决方案,我自己发布了答案,但不确定是否还有其他最佳解决方案。

          Javascript sn-p:

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

          模板 sn-p:

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

          【讨论】:

          【解决方案5】:

          不幸的是,在当前版本中是不可能的:(

          在您的示例中,您可以使用计算值进行计算并使用它。

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

          【讨论】:

            猜你喜欢
            • 2019-04-20
            • 1970-01-01
            • 2019-01-22
            • 1970-01-01
            • 2011-10-23
            • 1970-01-01
            • 2017-10-15
            • 2014-09-20
            • 1970-01-01
            相关资源
            最近更新 更多