VueJS Как я могу использовать вычисляемое свойство с V-для
Как я могу использовать вычисляемое свойство в списках. Я использую VueJS v2.0.2.
Вот HTML-код:
<div id="el">
<p v-for="item in items">
<span>{{fullName}}</span>
</p>
</div>
Вот код Vue:
var items = [
{ id:1, firstname:'John', lastname: 'Doe' },
{ id:2, firstname:'Martin', lastname: 'Bust' }
];
var vm = new Vue({
el: '#el',
data: { items: items },
computed: {
fullName: function(item) {
return item.firstname + ' ' + item.lastname;
},
},
});
5 ответов
Вы не можете создать вычисляемое свойство для каждой итерации. В идеале каждый из тех items
будет их собственный компонент, так что каждый может иметь свой собственный fullName
компьютерная собственность.
Что вы можете сделать, если вы не хотите создавать user
компонент, вместо этого используйте метод. Вы можете двигаться fullName
прямо из computed
собственность на methods
тогда вы можете использовать его как:
{{ fullName(user) }}
Также, обратите внимание, если вам нужно передать аргументы computed
скорее всего, вам нужен метод.
Что вам здесь не хватает, так это того, что ваш items
массив, который содержит все элементы, но computed
это один fullName
который просто не может выразить все fullName
в items
, Попробуй это:
var vm = new Vue({
el: '#el',
data: { items: items },
computed: {
// corrections start
fullNames: function() {
return this.items.map(function(item) {
return item.firstname + ' ' + item.lastname;
});
}
// corrections end
}
});
Тогда в представлении:
<div id="el">
<p v-for="(item, index) in items">
<span>{{fullNames[index]}}</span>
</p>
</div>
Конечно, способ, которым Билл представляет, работает, но мы можем сделать это с помощью компьютерных реквизитов, и я думаю, что это лучший дизайн, чем method
в итерациях, особенно когда приложение становится больше. Также, computed
имеет прирост производительности по сравнению с method
на некоторые обстоятельства: http://vuejs.org/guide/computed.html
Мне нравится решение, опубликованное PanJunjieæ½˜ä¿Šæ °. Суть проблемы заключается только в повторенииthis.items
один раз (на этапе создания компонента), а затем кеширование результата. Это, конечно, ключевое преимущество использования вычисляемой опоры вместо метода.
computed: {
// corrections start
fullNames: function() {
return this.items.map(function(item) {
return item.firstname + ' ' + item.lastname;
});
}
// corrections end
}
.
<p v-for="(item, index) in items">
<span>{{fullNames[index]}}</span>
</p>
Единственное, что мне не нравится, это то, что в разметке DOM fullNames
доступен по индексу списка. Мы могли бы улучшить это, используя.reduce()
вместо того .map()
в вычисляемой опоре для создания объекта с ключом для каждого item.id
в this.items
.
Рассмотрим этот пример:
computed: {
fullNames() {
return this.items.reduce((acc, item) => {
acc[item.id] = `${item.firstname} ${item.lastname}`;
return acc;
}, {});
},
},
.
<p v-for="item in items" :key="`person-${item.id}`">
<span>{{ fullNames[item.id] }}</span>
</p>
Примечание: в приведенном выше примере предполагается, что item.id
является уникальным, например, из типичного вывода базы данных.
Возможно, добавьте еще один v-for, который перебирает список из одного элемента:
<div id="el">
<p v-for="item in items">
<template v-for="fullName in [item.firstName + ' ' + item.lastName]">
<span>{{fullName}}</span>
</template>
</p>
</div>
Неприятно, но это то, что вы ищете: объект вокруг этого диапазона, который имеет свойство с именем fullName, которое содержит это конкретное значение.
И это не просто особенность тщеславия, потому что нам может потребоваться использовать это значение более чем в одном месте, например:
<span v-if="...">I am {{fullName}}</span>
<span v-else-if="...">You are {{fullName}}</span>
<span v-else>Who is {{fullName}}?</span>
Мой вариант использования заключался в том, что я строил даты в циклах v-for (да, другой календарь), например:
<v-row v-for="r in 5">
<v-col v-for="c in 7">
<template v-for="day in [new Date(start.getTime() + 24*60*60*1000*((c-1) + 7*(r-1)))]">
<span>
Some rendering of a day like {{day.getYear()}} and
{{day.getMonth()}} etc.
</span>
</template>
</v-col>
</v-row>
(Для краткости я опустил
:key="whatever"
настройки)
Я признаю, что лучше всего было бы переместить это в отдельный компонент, но если мы создадим новый компонент для каждого двухстрочного файла, подобного этому, и будем использовать этот компонент только в этом единственном месте, то мы просто загрязним другое пространство имен.
Может быть
v-let="day as new Date(...)"
директива была бы удобна для этой цели.
вы должны передать аргумент в вызове функции
<div id="el">
<p v-for="item in items">
<span>{{fullName(item)}}</span>
</p>
</div>