如何在Vue.js模板中定义临时变量

问题描述 投票:0回答:10
javascript vue.js vuejs2
10个回答
181
投票

我找到了一种非常简单(几乎神奇)的方法来实现这一目标, 它所做的只是定义一个内联(局部)变量,其中包含您要多次使用的值:

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

注意:

set
并不是
Vuejs
中的特殊道具,它只是用作变量定义的占位符。

Source
https://dev.to/pbastowski/comment/7fc9

CodePen
https://codepen.io/mmghv/pen/dBqGjM


更新:基于@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 us

虽然在这里基本上复制

users
数组没有意义,但这在其他需要调用昂贵的函数来获取数据的情况下可能很方便,但我认为你最好使用
computed
然后构建数组的属性。


14
投票

今天我需要这个并使用了

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

它成功了,我很惊喜,因为我不知道这是可能的


13
投票

根据您的模板判断,您可能最好使用计算属性,如已接受的答案中所建议的那样。

但是,由于问题标题有点宽泛(并且在 Google 上“Vue 模板中的变量”的排名相当高),我将尝试提供更通用的答案。


特别是如果您不需要转换数组中的每个项目,则计算属性可能有点浪费。子组件也可能有些过大,特别是如果它真的很小的话(这将使其成为 20% 的模板、20% 的逻辑和 60% 的 props 定义样板)。

我喜欢使用的一个非常简单的方法是一个小的辅助组件(我们称之为

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

6
投票

刚刚使用 vue3 进行了测试并且可以工作,我认为它可以普遍使用

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

设置变量时它不输出任何内容。

强制:

打开“(”

设置变量

关闭“, null)”


5
投票

这似乎是子组件的完美用例。您可以简单地将复杂的计算值作为属性传递给组件。

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


5
投票

这个怎么样:

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

CodePen:https://codepen.io/Vladimir-Miloevi/pen/xxJZKKx


3
投票

在某些情况下,

v-define
v-set
确实有助于防止重复执行某些操作(尽管计算属性有时更好)。您可以将
v-for
与仅具有该值的数组一起使用。

<template v-for="user in [getUser(id)]">
Hello {{ user.name }}!
</template>

与假设的

v-set
具有相同的效果:

<template v-set="user=getUser(id)">
Hello {{ user.name }}!
</template>

2
投票
<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>

1
投票

借用Mohamed的回答中的一个例子。 为了让它在 Vue3 中与 TypeScript 一起工作,我使用 Array.prototype.map() 在调用该函数的地方创建新对象。

const app = new Vue({
  el: '#app',
  data: {
    users: [1, 2, 3, 4],
    usersData: {
      1: {name: 'Mohamed', age: 29},
      2: {name: 'Ahmed', age: 27},
      3: {name: 'Zizo', age: 32},
      4: {name: 'John', age: 13},
    }
  },
  methods: {
    getUser(id) {
      return this.usersData[id];
    },
  },
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <div v-for="{ id, user } in users.map((id) => ({ id: id, user: getUser(id) }))" :key="id">{{ user.name }}, {{ user.age }} years old</div>
</div>


-3
投票

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>
© www.soinside.com 2019 - 2024. All rights reserved.