Standard and simple answers
- When used, computed is used as an attribute and methods as a method call.
- Computed can have getters and setters, so it can assign values, whereas methods can’t;
- Computed cannot accept multiple parameters, whereas methods can;
- Computed has caching, whereas Methods does not.
The answer is closer to the underlying principle
Vue’s handling of methods is relatively simple. It simply iterates through each attribute in the methods configuration, uses bind to bind its corresponding function to the current component instance, and copies its reference to the component instance
Vue’s handling of computed is a little more complicated.
When the component instance triggers the lifecycle function beforeCreate, it does a number of things, including processing for computed
It iterates through all the properties in a computed configuration, creates a Watcher object for each property, and passes in a function that is essentially the getter in a computed configuration, so that the getter collects dependencies as it runs
But unlike rendering functions, a Watcher created for a calculated property is not executed immediately, because it takes into account whether the calculated property will be used by the rendering function, and if not, it will not be executed. Therefore, when Watcher is created, it uses a lazy configuration, which prevents Watcher from executing immediately.
With lazy, Watcher stores two key attributes for caching: value and dirty
The value property is used to hold the results of the Watcher run. Affected by lazy, the value is initially undefined
The dirty attribute is used to indicate whether the current value is obsolete, that is, dirty, affected by lazy, which is initially true
After Watcher is created, Vue uses proxy mode to mount calculated properties to the component instance
When a calculated property is read, vue checks if its corresponding Watcher is dirty, if so, runs the function, evaluates the dependency, and gets the corresponding value, saves it in Watcher’s value, then sets dirty to false, and returns.
If dirty is false, watcher’s value is returned
The neat thing is that in dependency collection, the dependent data is collected not only into the Watcher of the calculated property, but also into the Watcher of the component
When a dependency change is calculated, Watcher first triggers the execution of the calculation property, which simply sets dirty to true and does nothing.
Because of the dependency on the Watcher that is also collected for the component, the component is re-rendered, which in turn reads the calculated properties, and since the calculated properties are now dirty, the getter is re-run for the calculation
For setters that evaluate properties, it’s extremely simple to just run the setter when you set the evaluated property