我找到了一种非常简单(几乎神奇)的方法来实现这一目标, 它所做的只是定义一个内联(局部)变量,其中包含您要多次使用的值:
<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
然后构建数组的属性。
今天我需要这个并使用了
<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>
它成功了,我很惊喜,因为我不知道这是可能的
根据您的模板判断,您可能最好使用计算属性,如已接受的答案中所建议的那样。
但是,由于问题标题有点宽泛(并且在 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 对插槽的处理方法略有不同。首先,
<Pass>
组件源码需要这样调整:
const Pass = {
render() {
return this.$slots.default(this.$attrs)
}
}
刚刚使用 vue3 进行了测试并且可以工作,我认为它可以普遍使用
{{ (somevariable = 'asdf', null) }}
<span v-if="somevariable=='asdf'">Yey</span>
<span v-else>Ney</span>
设置变量时它不输出任何内容。
强制:
打开“(”
设置变量
关闭“, null)”
这似乎是子组件的完美用例。您可以简单地将复杂的计算值作为属性传递给组件。
https://v2.vuejs.org/v2/guide/components.html#Passing-Data-to-Child-Components-with-Props
这个怎么样:
<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>
在某些情况下,
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>
<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>
借用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>
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>