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>
In 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
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>
export statement, it is just a plain javascript variable that you can use anywhere inside the script tag. It is not bound to the component, or related to Vue in any way.
Pros:
<script> element's scope.this.<template> tags.
Pros:
<template>$vm.data.someVarData, i.e. the variable is added to the Vue component's instance.<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
});
},