Reputation: 10068
I have a users data object which has a first_name and last_name and a computed property which returns the full name but the following doesnt seems to work in my v-for directive?
new Vue({
el: '#content',
data: {
"users": [
{
"id": 3,
"first_name": "Joe",
"last_name": "Blogs"
},
{
"id": 3,
"first_name": "Jane",
"last_name": "Doe"
}
]
},
computed: {
fullName: function (user) {
return user.first_name + ' ' + user.last_name;
}
}
});
<tr v-for="user in users | orderBy fullName(user)">
<td class="col-xs-6 col-sm-3 col-md-3 col-lg-3">
{{fullName(user)}}
</td>
<tr>
Upvotes: 27
Views: 71963
Reputation: 2401
I don't believe that a computed property in Vue.js can accept an argument, they are supposed to be able to build themselves without additional interaction. I believe that your fault was that you wrote a method and then tried to register it as a computed property.
So it should be a simple fix to just change the registration of your function from computed
to methods
which it really is.
methods: {
fullName: function (user) {
return user.first_name + ' ' + user.last_name;
}
}
This way you will not have to change any of your other code.
Upvotes: 36
Reputation: 17085
Another reason: properties with an underscore (_
) prefix will not trigger computed
.
Surprise: _
and $
prefixes are reserved in Vue.
Upvotes: 1
Reputation: 1170
I have a similar question here: How to dinamically make computed in Vue.js, under dynamically loaded data.
But, in the end here is the possible solution for you from the conclusion that i get after discussing and trial and error. There are several ways:
item.computedProperty()
in the UI (with double bracket)items
, create a watcher that will assign the computed to each of the element, then put inside extendedItems
. the computed function will become reactive when bound to UI, so the UI then will use extendedItems
instead of items
this.$set
to manually set and enable reactivity to the computed.This is using computed with function from the solution number 1:
new Vue({
el: '#content',
data: {
"users": [
{
"id": 3,
"first_name": "Joe",
"last_name": "Blogs"
},
{
"id": 3,
"first_name": "Jane",
"last_name": "Doe"
}
]
},
computed: {
extendedUsers: function(){
var users = this.users;
for (var i in users)
this.extendUser(users[i])
},
extendUser: function(user){
user.fullName = function(){
return user.first_name + " " + user.last_name;
}
}
}
});
<tr v-for="user in users | orderBy user.fullName()">
<td class="col-xs-6 col-sm-3 col-md-3 col-lg-3">
{{user.fullName()}}
</td>
<tr>
Upvotes: 0
Reputation: 1272
i had a similar case, when i use a props property with undecleared nested properties. For some reason i made this work doing a
console.log(user.first_name)
fullName: function (user) { console.log(user.first_name) return user.first_name + ' ' + user.last_name; }
Also, i made this work using lambda expression https://stackoverflow.com/a/46234335/726751
computed: {
fullName: _this => {
return _this.user.first_name + ' ' + _this.user.last_name;
}
}
Upvotes: 1
Reputation: 167
You can map the users in your computed property and use that mapped array like this:
computed: {
fullName: function () {
return this.users.map(
item => item.first_name + ' ' + item.last_name
);
}
}
Then in view you can do something like:
<tr v-for="(user, item) in users">
<td class="col-xs-6 col-sm-3 col-md-3 col-lg-3">
{{fullName[item]}}
</td>
<tr>
And I am using es6 arrow function. If you don't want to use arrow function then you can do something like:
return this.users.map(
function(item) {return item.first_name + ' ' +item.last_name}
);
Upvotes: 2
Reputation: 247
Try to disable cache on the computed property, like mentioned in https://github.com/vuejs/vue/issues/1189. Doing this, the computed value will be always recalculated.
computed: {
fullName: {
cache: false,
get() {
return user.first_name + ' ' + user.last_name;
}
}
}
Upvotes: 23
Reputation: 179994
Computed properties don't support nesting like that.
Proof and some workarounds/alternative solutions: https://github.com/vuejs/vue/issues/66
Upvotes: 3