There are three main ways to store variables and/or react to variable changes in Vue components.
datacomputed- Watch for changes in
watcher
So, how to decide when to use what? (that is 3-in-1 question, I outwit myself)
Although these sections look similar, they serve different functions. Evaluate the variables against the following considerations when you are in doubt.
| Description | Data | Computed | Watcher |
|---|---|---|---|
| Store variables | Store local variables | Computed variables. Can be static, derived from other variables, or can be static functions | Does not store variables - only watches them. |
| React to variable value changes | Y | Y | Y |
| Cached? | Y | Y | N/A |
| Scope | Local to component | Local to component, but can derive/make calculations with variables from props, store, etc. | Can watch local or store variables and react to changes |
Can be referred by <template> | Y | ||
e.g. {{ myName }} | Y | ||
{{ myCalcName }} | N/A | ||
Can be referred by <script> methods | Y | ||
this.myName | Y | ||
this.myCalcName | N/A | ||
| Perform action when value changes | N | N | Y |
| Consequence of a value change | Change UI to react to change | Change UI | Perform action - local/vuex |
| Can change other variable values | N | Y | Y |
See examples below.
Data
Data is a function in the component and can have one or more variables. Scope of these variables is limited to the component. Variables can be initialized to a value, or just assigned a type.
<script>
export default {
data() {
return {
valid: true,
num: 123,
name: "Neo",
status: String,
};
},
};
</script>
Computed
Computed is an object within a component, and can have simple variables, or functions.
<script>
export default {
computed: {
// refer to state or getter from store
...mapState("todo", ["numTodo"]),
// not sure why you would want to do this, but ok.
sumZero: 0,
// sum as a function
sumSum: () => {
return this.num1 + this.num2;
},
// function that calculates value from other values
// called simply as this.fullAddress or {{ fullAddress }}
// also a function
fullAddress() {
let addr = this.contact.address_1 ? this.contact.address_1 + ", " : "";
addr += this.contact.address_2 ? addr + this.contact.address_2 : addr;
return addr;
},
// can be updated and retrieved through get/set
sumTotal: {
get() {
return this.num1 + this.num2;
},
set(value) {
this.total = value;
},
}, // sumTotal
},
};
</script>
You can see that a method can also calculate values similar to computed and those calculated values can then be stored in data. But computed has two big advantages -
- Values are cached. You don’t need to do anything other than store values as computed. Computed values are picked up from cache when there is re-render. Methods, on the other hand, are always run whenever re-render happens - thereby causing computations to occur even when the source has not changed
- React to changes. When source is changed, the computed values automatically change - there is no need for a separate
watcher
Watcher
<script>
export default {
watch: {
// react to changes
// calculate other variables
startDate: function () {
this.endDate = this.startDate + 10;
},
},
};
</script>
Further Reading
Go to the excellent Vue documentation on computed properties vs. watchers