I have an array of objects inside my Vue instance, and for each item I'd like to write a Computed property.
Each object has only two properties: firstName
and lastName
. I would like to write a Computed property for each named 'fullName', which is just a concatenation of firstName
and lastName
.
I'm familiar with implementing Computed properties of data object properties of a Vue instances, but when it es to doing so with elements of an array, I get confused.
Currently, my code is this:
var app = new Vue({
el: '#app',
data: {
names: [{
firstName: 'Mike',
lastName: 'McDonald',
done: false
},
{
firstName: 'Alex',
lastName: 'Nemeth',
done: false
},
{
firstName: 'Nate',
lastName: 'Kostansek',
done: true
},
{
firstName: 'Ivan',
lastName: 'Wyrsta',
done: true
}
]
},
puted: {
fullName: function(name) {
return name.lastName + ', ' + name.firstName;
}
}
methods: {
toggle: function(name) {
name.done = !name.done;
}
}
});
<script src="/[email protected]/dist/vue.js"></script>
<div id='app'>
<ol>
<li v-for='name in names'>
<input type='checkbox' v-bind:checked='name.done' v-on:change='toggle(name)' />
<span v-if='!name.done'>{{ fullName(name) }}</span>
<del v-else>{{ fullName(name) }}</del>
</li>
</ol>
</div>
I have an array of objects inside my Vue instance, and for each item I'd like to write a Computed property.
Each object has only two properties: firstName
and lastName
. I would like to write a Computed property for each named 'fullName', which is just a concatenation of firstName
and lastName
.
I'm familiar with implementing Computed properties of data object properties of a Vue instances, but when it es to doing so with elements of an array, I get confused.
Currently, my code is this:
var app = new Vue({
el: '#app',
data: {
names: [{
firstName: 'Mike',
lastName: 'McDonald',
done: false
},
{
firstName: 'Alex',
lastName: 'Nemeth',
done: false
},
{
firstName: 'Nate',
lastName: 'Kostansek',
done: true
},
{
firstName: 'Ivan',
lastName: 'Wyrsta',
done: true
}
]
},
puted: {
fullName: function(name) {
return name.lastName + ', ' + name.firstName;
}
}
methods: {
toggle: function(name) {
name.done = !name.done;
}
}
});
<script src="https://cdn.jsdelivr/npm/[email protected]/dist/vue.js"></script>
<div id='app'>
<ol>
<li v-for='name in names'>
<input type='checkbox' v-bind:checked='name.done' v-on:change='toggle(name)' />
<span v-if='!name.done'>{{ fullName(name) }}</span>
<del v-else>{{ fullName(name) }}</del>
</li>
</ol>
</div>
And here is the respective jsFiddle
Share Improve this question edited Jul 23, 2020 at 23:10 Boussadjra Brahim 1 asked Nov 20, 2018 at 16:04 DelfinoDelfino 1,0094 gold badges22 silver badges47 bronze badges 1- 1 Try to reduce the number of function calls in your template. The function results are not cached, meaning that pretty much every change in data causes a full re-render. Using a puted, by creating an array of pre-puted objects can greatly improve your apps performance. See @Boussadjra's updated (2nd) example – Daniel Commented Nov 20, 2018 at 16:31
2 Answers
Reset to default 7It's remended to return a function with name
as argument from the puted property :
var app = new Vue({
el: '#app',
data: {
names: [{
firstName: 'Mike',
lastName: 'McDonald',
done: false
},
{
firstName: 'Alex',
lastName: 'Nemeth',
done: false
},
{
firstName: 'Nate',
lastName: 'Kostansek',
done: true
},
{
firstName: 'Ivan',
lastName: 'Wyrsta',
done: true
}
]
},
puted: {
fullName(){
return (name)=>name.lastName + ', ' + name.firstName;
},
toggle() {
return (name)=>name.done = !name.done;
}
},
});
<script src="https://cdn.jsdelivr/npm/[email protected]/dist/vue.js"></script>
<div id='app'>
<ol>
<li v-for='name in names'>
<input type='checkbox' v-bind:checked='name.done' v-on:change='toggle(name)' />
<span v-if='!name.done'>{{ fullName(name) }}</span>
<del v-else>{{ fullName(name) }}</del>
</li>
</ol>
</div>
Another solution is to loop through names
array inside a puted property by concatenating firstname
and lastname
, after that return this array and loop through it in your template
var app = new Vue({
el: '#app',
data: {
names: [{
firstName: 'Mike',
lastName: 'McDonald',
done: false
},
{
firstName: 'Alex',
lastName: 'Nemeth',
done: false
},
{
firstName: 'Nate',
lastName: 'Kostansek',
done: true
},
{
firstName: 'Ivan',
lastName: 'Wyrsta',
done: true
}
]
},
puted: {
fullNames() {
return this.names.map(name => {
let fl = {};
fl.fname = name.firstName + ", " + name.lastName;
fl.done = name.done;
return fl;
})
}
},
methods: {
fullName: function(name) {
return name.lastName + ', ' + name.firstName;
},
toggle: function(name) {
name.done = !name.done;
}
}
});
<script src="https://cdn.jsdelivr/npm/[email protected]/dist/vue.js"></script>
<div id='app'>
<ol>
<li v-for='name in fullNames'>
<input type='checkbox' v-bind:checked='name.done' v-on:change='toggle(name)' />
<span v-if='!name.done'>{{ name.fname }}</span>
<del v-else>{{ name.fname }}</del>
</li>
</ol>
</div>
You can't use the 'puted' with a parameter. Most probably you want to use a method:
example
<span>{{ fullName('Hi') }}</span>
methods: {
fullName(param) {
return `${this.param} ${this.firstName} ${this.lastName}`
}
}