Reputation: 1348
I have a custom-directive :myMethod="loadProfile(currentUser)" which loads the JSON when the component is loaded. I use mapGetters
from Vuex
but surprisingly, this method is also working very well..I have a dilemma if this is also correct or performance-wise compared to other approaches like calling methods in mounted
or created
hooks (which I also tried)? Which is better to call on the hook or custom-directive?
Here is my sample code:
<template v-if="currentUser.username === 'admin'">
... //
<template v-else>
<div :myMethod="loadProfile(currentUser)"></div>
</template>
Vuex Getters
computed: {
...mapGetters([
'currentUser',
])
}
Method
loadProfile(payload){
this.user.last_name = payload.last_name,
this.user.first_name = payload.first_name,
this.user.image = ( payload.image === 'no_avatar.png' ? '/image/no_avatar.png' : '/storage/images/'+ payload.image)
}
Upvotes: 0
Views: 361
Reputation: 21030
Vue.js directives are only meant to do some low-level DOM manipulations that you cannot do with a regular component. So in short, you should not be doing what you are currently doing.
Now on to longer answer:
In your code, you are doing something like this: <div :myMethod="loadProfile(currentUser)"></div>
. If :myMethod
is a directive then it should be v-myMethod=""
instead of :myMethod=""
. Latter syntax i.e. colon syntax refers to props
and not directive. So, it means your code is not really executing directive. Just treating myMethod
as some prop.
Second, doing :myMethod="loadProfile(currentUser)"
doesn't mean you are doing anything within an actual directive code. It is still being called from the component template.
Third, if we look at your loadProfile()
method implementation, then it is not a function that returns a value. It is simply a function modifying component instance using this
. If all you need to do this, then you don't need a directive or prop.
Fourth, doing :myMethod="loadProfile(currentUser)"
will work but it looks awkward definitely not readable. Instead, you should rely on a watcher or computed property. It is the idiomatic way of doing things in Vue.js. Example watcher implementation would look like:
watch: {
currentUser(newVal) {
this.user.last_name = newVal.last_name,
this.user.first_name = newVal.first_name,
this.user.image = ( newVal.image === 'no_avatar.png' ? '/image/no_avatar.png' : '/storage/images/'+ newVal.image)
}
}
As far as the performance is concerned, you should not worry about it. Performance penalty if any will be negligible.
Upvotes: 1
Reputation: 20745
Don't use methods unless you really have to. In this case there seems to be little reason to call loadProfile
without currentUser
, so lets just move it to a computed property:
computed: {
...mapGetters([
'currentUser'
]),
actualUser () {
// Make a shallow copy
const user = { ...this.user };
if (this.currentUser) {
user.lastName = this.currentUser.lastName;
user.firstName = this.currentUser.firstName;
user.image = (this.currentUser.image === 'no_avatar.png' ? '/image/no_avatar.png' : `/storage/images/${this.currentUser.image}`);
}
return user;
}
}
Why use a computed property? Computed properties are calculated and updated whenever their dependencies update. When the dependencies stay constant, the computed property will just be loaded from cache. This is a better for performance and makes it so you don't have to worry about when to update your data yourself.
As for the use of a directive. I most cases you don't need to use directives. You don't send a function reference to the directive here, but rather the evaluated result of the method, so doing <div :myMethod="actualUser"></div>
would work too. You may want to make sure that what you are doing cannot be done with actual components. Components are re-usable and much easier to read than the code in a custom directive.
Upvotes: 1