Could you explain the difference between declaring variables in different ways. When I should use these ways of declaring?
<script>
const someVariable = 12345
export default {
name: 'App',
}
</script>
<script>
export default {
name: 'App',
data() {
return {
someVariable: 12345
}
}
}
</script>
Could you explain the difference between declaring variables in different ways. When I should use these ways of declaring?
<script>
const someVariable = 12345
export default {
name: 'App',
}
</script>
<script>
export default {
name: 'App',
data() {
return {
someVariable: 12345
}
}
}
</script>
Share
Improve this question
asked Sep 23, 2021 at 14:24
Daniil ShelestDaniil Shelest
1131 silver badge7 bronze badges
1
- 5 The first one is not available in the template and is not reactive (i.e. nothing updates automatically when it changes). – deceze ♦ Commented Sep 23, 2021 at 14:25
2 Answers
Reset to default 6In the first one, you can't use the someVariable
in your template
<script>
const someVariable = 12345
export default {
name: 'App',
}
</script>
<template> <p> {{someVariable}} </p> </template> //doesn't work
Available in Vue3:
to make it work you can add a setup
keyword in your script but you have to wrap your variable value with ref(...)
or reactive(...)
if you want to make it reactive to changes More info
<script setup>
const someVariable = 12345
export default {
name: 'App',
}
</script>
<template> <p> {{someVariable}} </p> </template> //works (you can see the data)
A typical Single File Component will be like so:
<template>
...
</template>
<script>
...
</script>
- If you define a variable outside the
export
statement, it is just a plain javascript variable that you can use anywhere inside the script tag. It is not bound to the ponent, or related to Vue in any way. Pros:- Your variable exists in the entire
<script>
element's scope. - You can use it inside inner functions that don't have a binding to
this
.
- Your variable exists in the entire
- If you define a variable inside data function, or to put it more accurately, define a property for ponent instance's data object, then it is bound to the ponent, and hence available inside the
<template>
tags. Pros:- The variable can be referenced from
<template>
- You can take advantage of Vue's reactivity. You can define puted properties on this variable. When you use it in the template, the html is updated to reflect any change in this variable.
- You can pass it as props to child ponents.
- You can debug things easily using Vue devtools, you can watch changes to your variable. You can also log the variable into console like
$vm.data.someVarData
, i.e. the variable is added to the Vue ponent's instance.
- The variable can be referenced from
<template>
<div>
<div :class="someVarData"/> <!-- This is Ok -->
<div :class="someVar"/> <!-- This is not Ok -->
</div>
<template>
<script>
const someVar = "blah";
export default {
data() {
return {
someVarData: "blahData",
};
},
mounted() {
const el = document.getElementById('myId');
el.addEventListener('mouseenter', function () {
console.log(someVar); // This is Ok
console.log(this.someVarData); // This is not Ok
});
},
beforeRouteEnter() { // <--- Vue-router's Navigation guard
console.log(someVar); // This is Ok
console.log(this.someVarData); // This is not Ok
},
</script>
As such you should avoid defining variables outside export since they make it harder to understand the flow of your code. There's almost always some way you can redesign your approach to not use variables outside export.
For e.g. in the above example, you can still use your data variable inside the mounted
hook and the navigation guard with some changes:
mounted() {
const el = document.getElementById('myId');
el.addEventListener('mouseenter', () => {
console.log(someVar); // This is Ok
console.log(this.someVarData); // Ok - works because we change the function to arrow function, so it is bound to the instance's `this`
});
el.addEventListener('mouseenter', function () {
console.log(someVar); // This is Ok
console.log(this.someVarData); // Ok - works because we have manually bound the function to the instance's `this`
}.bind(this));
},
beforeRouteEnter(to, from, next) { // <--- Vue-router's Navigation guard
console.log(someVar); // This is Ok
console.log(this.someVarData); // This is not Ok
next((vm) => {
console.log(vm.someVarData); // Ok - Navigation guard's next function provides the instance's context as a callback parameter
});
},