簡體   English   中英

如何在Vue.js模板中定義一個臨時變量

[英]How to define a temporary variable in Vue.js template

這是我當前的模板:

<a-droppable v-for="n in curSize" :key="n - 1" :style="{width: `${99.99 / rowLenMap[orderList[n - 1]]}%`, order: orderList[n - 1]}">
  <a-draggable :class="{thin: rowLenMap[orderList[n - 1]] > 10}">
    <some-inner-element>{{rowLenMap[orderList[n - 1]]}}</some-inner-element>
  </a-draggable>
</a-droppable>

問題是我要多次寫rowLenMap[orderList[n - 1]] ,我怕vue.js引擎也會計算多次。

我想要的是這樣的:

<a-droppable v-for="n in curSize" :key="n - 1" v-define="rowLenMap[orderList[n - 1]] as rowLen" :style="{width: `${99.99 / rowLen}%`, order: orderList[n - 1]}">
  <a-draggable :class="{thin: rowLen > 10}">
    <some-inner-element>{{rowLen}}</some-inner-element>
  </a-draggable>
</a-droppable>

我認為在技術上實現起來並不困難,因為它可以通過使用v-for="rowLen in [rowLenMap[orderList[n - 1]]]"類的東西笨拙地解決。 那么有沒有簡潔官方的解決方案呢?

我找到了一種非常簡單(幾乎是神奇)的方法來實現這一點,它所做的只是定義一個內聯(局部)變量,其中包含您要多次使用的值:

<li v-for="id in users" :key="id" :set="user = getUser(id)">
  <img :src="user.avatar" />
  {{ user.name }}
  {{ user.homepage }}
</li>

注意: set不是Vuejs中的特殊道具,它只是用作我們變量定義的占位符。

Sourcehttps ://dev.to/pbastowski/comment/7fc9

代碼筆: https : CodePen


更新:基於@vir us的評論

這不適用於事件,例如@click="showUser(user)"不會傳遞正確的用戶,而是始終是最后評估的用戶,這是因為user臨時變量將被重新使用和替換循環的每一圈。

所以這個解決方案只適用於模板渲染,因為如果組件需要重新渲染,它將再次重新評估變量。

但是如果你真的需要將它與事件一起使用(雖然不推薦),你需要定義一個外部數組來同時保存多個變量:

<ul :set="tmpUsers = []">
  <li v-for="(id, i) in users" :key="id" :set="tmpUsers[i] = getUser(id)" @click="showUser(tmpUsers[i])">
    <img :src="tmpUsers[i].avatar" />
    {{ tmpUsers[i].name }}
    {{ tmpUsers[i].homepage }}
  </li>
</ul>

https://codepen.io/mmghv/pen/zYvbPKv

學分: @vir 我們

雖然在這里基本上復制users數組沒有意義,但這在您需要調用昂貴的函數來獲取數據的其他情況下可能很方便,但我認為您最好使用computed屬性來構建數組然后。

從您的模板來看,您可能最好使用計算屬性,正如接受的答案中所建議的那樣。

但是,由於問題標題有點寬泛(並且在 Google 上出現的“Vue 模板中的變量”相當高),我將嘗試提供更通用的答案。


特別是如果您不需要轉換數組的每個項目,那么計算屬性可能有點浪費。 子組件也可能是矯枉過正,特別是如果它真的很小(這將使它成為 20% 的模板、20% 的邏輯和 60% 的道具定義樣板)。

我喜歡使用的一個非常簡單的方法是一個小的幫助組件(我們稱之為<Pass> ):

const Pass = {
  render() {
    return this.$scopedSlots.default(this.$attrs)
  }
}

現在我們可以像這樣編寫你的組件:

<Pass v-for="n in curSize" :key="n - 1" :rowLen="rowLenMap[orderList[n - 1]]" v-slot="{ rowLen }">
  <a-droppable :style="{width: `${99.99 / rowLen}%`, order: orderList[n - 1]}">
    <a-draggable :class="{thin: rowLen > 10}">
      <some-inner-element>{{rowLen}}</some-inner-element>
    </a-draggable>
  </a-droppable>
</Pass>

<Pass>通過創建一個作用域插槽來工作。 Vue.js 文檔中閱讀更多關於作用域槽的信息,或者在我寫的關於該主題的dev.to 文章中了解上述方法。


附錄:Vue 3

Vue 3 對插槽的處理方式略有不同。 首先, <Pass>組件源碼需要調整如下:

const Pass = {
  render() {
    return this.$slots.default(this.$attrs)
  }
}

今天我需要這個並像這樣使用<template>標簽和v-for
我拿了這段代碼

<ul>
  <li v-for="key in keys" 
      v-if="complexComputation(key) && complexComputation(key).isAuthorized">
    {{complexComputation(key).name}}
  </li>
</ul>

改成這個

<ul>
  <template v-for="key in keys">
    <li v-for="complexObject in [complexComputation(key)]"
        v-if="complexObject && complexObject.isAuthorized">
      {{complexObject.name}}
    </li>
  </template>
</ul>

它奏效了,我很驚喜,因為我不知道這是可能的

這似乎是子組件的完美用例。 您可以簡單地將復雜的計算值作為屬性傳遞給組件。

https://v2.vuejs.org/v2/guide/components.html#Passing-Data-to-Child-Components-with-Props

剛剛使用 vue3 進行了測試並且有效,我認為它普遍適用

{{ (somevariable = 'asdf', null) }}
<span v-if="somevariable=='asdf'">Yey</span>
<span v-else>Ney</span>

它在設置變量時不輸出任何內容。

強制的:

打開“(”

設置你的變量

關閉“,空)”

<template>
  <div>
    <div v-for="item in itemsList" :key="item.id">
      {{ item.name }}

      <input v-model="item.description" type="text" />
      <button type="button" @click="exampleClick(item.id, item.description)">
        Click
      </button>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      items: [
        {
          id: 1,
          name: 'Name1',
        },
        {
          id: 2,
          name: 'Name2',
        },
      ],
    }
  },
  computed: {
    itemsList() {
      return this.items.map((item) => {
        return Object.assign(item, { description: '' })
      })
    },
  },
  methods: {
    exampleClick(id, description) {
      alert(JSON.stringify({ id, description }))
    },
  },
}
</script>

我找到了這個簡單的方法。
我在 vue2 上運行了這個。

<li v-for="id in users" :key="id">
  <span style="display: none;">{{user = getUser(id)}}</span>
  <img :src="user.avatar" />
  {{ user.name }}
  {{ user.homepage }}
</li>

這個怎么樣:

<div id="app">
  <div
    v-for="( id, index, user=getUser(id) ) in users"
    :key="id"
  >
    {{ user.name }}, {{ user.age }} years old
    <span @click="show(user)">| Click to Show {{user.name}} |</span>
  </div>
</div>

代碼筆: https://codepen.io/Vladimir-Miloevi/pen/xxJZKKx

curSize是一個數組。 您的臨時值包含相應的隱含數組sizedOrderList = curSize.map(n => orderList[n-1]) 如果您將其定義為計算,您的 HTML 將變為

<a-droppable v-for="n, index in sizedOrderList" :key="curSize[index]" :style="{width: `${99.99 / rowLenMap[n]}%`, order: n}">
  <a-draggable :class="{thin: rowLenMap[n] > 10}">
    <some-inner-element>{{rowLenMap[n]}}</some-inner-element>
  </a-draggable>
</a-droppable>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM