What is the difference between watch and computed methods in vuejs - vue.js

They both seem to do the same thing, and I can't tell when to use which

Computed properties are just like the data properties. The literal meaning of computed is 'calculated using given values'.
Just as the meaning suggests computed properties are a calculated result of its dependent values(in vuejs data properties, props)
for example:
data:{
lowerCase: 'abcd'
},
computed:{
uppercase(){
return this.lowerCase.toUpperCase();
}
}
in the above example the computed property uppercase is dependent on data property lowerCase. It converts(computes) the letters into uppercase.
whenever lowercase changes , so any template bindings using this computed property automatically update.
Watch properties are more general and in one way more powerful(bit expensive) to watch for changes in data properties.
You can perform complex functions, asynchronous tasks in watchers. The example given in the documentation is a good example of using a watcher.
Summarizing the differences:
Computed properties unlike watched properties should return a value.
computed properties are just like data properties and can be used
in template using {{ }} but watchers cannot be used. Watchers should perform logic to update the data properties which are used in the template.

Computed properties are basically “virtual” properties that are evaluated when they are first used. They will be automatically cached until changes in the component require a reevaluation of the property.
Watch properties are just a mechanism to detect changes in properties, allowing you to perform custom logic.
Since watchers are much more powerful, you can use them to do the same that computed properties do: Basically, you would watch all dependent properties and whenever a value changes, you would recompute the property and store it in the Vue instance’s data.
Unless you require complex logic, computed properties will already do this in a more declarative way: You do not need to listen explicitly on all dependent properties but rely on Vue to automatically detect which properties your computed property depends on. So you just declaratively state how to compute the computed property and don’t need to worry about something else. Computed properites also already come with a good caching mechanism, something you would have to do yourself with watchers.
See also the guide on computed properties and watchers. One example they give for watchers is a debounced service call that would load additional data.
In general though, the gist is: Try to use computed properties for everything. If it won’t work as a computed property, use a watcher.

Its difficult to express this more clearly than the doc
tldr; computed properties are reactive. Their output is cached, and automatically updates if anything used in the function changes. Changes flow out onto the page, without us needing to worry about when or why. watch is "imperative and repetitive". It runs when the thing you're watching changes, like a listener. You then are responsible for how the result is stored and used.
You can do everything with events, but you should try to move up the food chain if you can. Prefer computed to watch.

Related

Is it bad to use a watch in a child component?

In my project, I need to know the changes in the child components in real time from the parent component.
So I'm going to use watch in a child component to emit event to the parent component whenever the data in the child component changes.
Is this a bad way? I'm afraid there's an unnecessary overload in this flow.
If you have a better way, please recommend it.
There's nothing wrong with this approach. Vue is very efficient in the way it detects changes, and there shouldn't be an unnecessary overload, unless you watch more than you need to. You shouldn't notice any performance issues unless you have a huge object graph (eg thousands of objects being watched).
Make sure you only watch the properties that require change detection, and only use deep:true if you really need to.

Vue - use vuex instead of eventbus for calculations with nested data & components

I have app when bind big JSON object into component, then some parts from this object into next components etc. - it's structure with many deep levels, but object is not copied, I use advantage that objects are passing by reference.
Components on the lowest level have fields like "price", "qty" etc. When user modifies them, I updated object and run recalculation using global eventbus - after recalculation is done, I also use eventbus to forceUpdate some components. For example parents of these with fields price/qt, to refresh "total" amounts in categories.
Now I move some code to vuex and consider also here. Think that recalculation after commit will be ok. The question is - how can I modify this big object using commit from children components? The problem is that commit must "know" what part of object has been modified (for example, one element inside one of many categories)... I can do it in other way, pass child and parent data in commit and update parent but... will it work? I also need reference to do this in proper way...
Maybe still use binding to pass elements, but call store action to only make recalculation (not sure, that provides automatic refreshes on all required modules).
Or maybe other, better solution?
I think you have some problems with architecture. Main idea here is to have some container (smart) component, that is connedcted with store (vuex), and simple (stupid) components, that recieve data from props. Also you must divide your store into modules, so it'll be easy to maintain. This approach will allows you to modify exactly pieces of data you want.

When to use getters

So I know getters are primarily used to return state data that is manipulated in some way but is it best practice to create a getter if you just want to return the state value itself without mutating or anything?
I don't think it necessarily saves any code, if anything creates more, by creating a getter to return all the values I need.
Where I have the option, I personally always prefer getters (and C#-style properties) over direct memeber variable accesses be it internally from within the same class or externally from outside the class for two different reasons:
1- They are great when debugging “access points” (for example if you had to monitor who accesses a member variable and when then you just put a print or a breakpoint in the getter instead of doing loads of searching in your code)
2- If in the future you need to change the way a member variable is defined and/or used then getters give you a single point of focuse/change which can be changed to reflect changes in the definitions and meanings of the actual backing member variable
Note the same applies to setters too.
In C++ it is not that common practice but I don’t remember the last time I did not use getter/setters for something!
Hope this helps!
Getters are essentially good for derived states: https://vuex.vuejs.org/guide/getters.html
It's also a good practice to maintain your getters in the same place and use mapGetters in your reactive components.

Vue watchers and components

Vue newbie here - we are introducing Vue into an existing application bit by bit and therefore I am slightly constricted by this with regards to the back end. The Vue template gets an array of objects from the Django backend. Some of the objects returned are parents and others are children of the parents - identified by the parent_id.
These are rendered happily using various components to encapsulate some of the functionality.
The update end point for the back end is configured to take one single object and update the database accordingly, therefore the watcher must be able to identify which of the array of objects has been updated. From my understanding this isn’t possible for objects/arrays in Vue/Js as the before/after values aren’t available for anything other than simple types.
The workaround I have put in place is to clone the array of objects in a computed property, and then compare the new array to the computed array to identify which object has been modified in order to send that back to the back end.
Is this best practice, or am I going to fall foul to this decision later on down the line?
many thanks for your help
It would be better if you give the objects of the array their own components, so you have a vue component that takes as a prop the object and you then use a v-for on the array to create one instance of the "object component" for each object in the array.
Then you can have a watcher on the object prop in the object component and you will know exactly which object has changed and get better control.

When to use method over computed property setter and vice versa?

When using Vue.js, when should you use a method or a computed property setter? There seems to be little distinction in the documentation, or numerous articles. Usually articles present computed property setters as little more than a footnote.
Given that both methods and setters accept parameters, is there a particular reason you'd use one or the other? As far as I can see methods would be all you need.
Edit:
This is literally not a repost because the linked SO answer contains the word setter once and only in vague passing:
computed properties are converted into a property of the Vue with a getter and sometimes a setter.
Great, so how does this elaborate on the subject of this post, when to use a SETTER vs a method?
Computed properties are cached so they can benefit you when it comes to performance. They do not work like methods, as they do not accept arguments.
I use them mostly to modify existing data or make it easier to access nested data.
The part about caching is something that can end up being a hassle. They will always cache unless their direct dependencies change. Properties within computed properties that are within controls blocks will usually not update the computed property(not seen as a direct dependency).
This is something you need to be aware of.
When using things like large v-for lists you will want to to take advantage of the caching ability of computed properties since unlike with a method you won't have to perform the logic inside of it over and over, unless the direct dependencies of the computed property change.
Computed properties should be used to display data relative to existing data. While methods should be used to do an action and/or change data.