'Vue JS: reactive syntax
While I was trying to grasp reactivity fundamentals and its syntax I've encountered following problem. Consider this snippet:
const app = Vue.createApp({
data: dataFunction,
methods: {method1: methodImpl}
})
var dataObj = {
title: 'Holiday',
author: 'Stanley Middleton',
age: 45
}
function dataFunction (){
return dataObj
}
var methodsObj = {
method1: methodImpl
}
function methodImpl (){
this.title = 'Infinite Jest'
}
app.mount('#app')
and html behind it:
<div id="app">
[...]
<div @click="method1">change book title</div>
</div>
This code works and I was able to extract data
into separate function and object but how can I do it with method
?
This methods: methodsObj
doesn't work - obviously. I want to be able to use my methodsObj
in createApp
initialization. Is it possible?
I know it is purely academic but such exercises help me understand syntax and object relations.
Solution 1:[1]
In JavaScript, var
s are hoisted, but their initializations are not. function
s and their definitions are also hoisted. Your code relies on hoisting, which can be problematic.
Here's a visualization of the hoisting in your original working code:
// ? HOISTED DECLARATIONS
var dataObj = undefined;
function dataFunction (){
return dataObj
}
var methodsObj = undefined;
function methodImpl (){
this.title = 'Infinite Jest'
}
// ? HOISTED DECLARATIONS
const app = Vue.createApp({
data: dataFunction,
methods: {method1: methodImpl} // ? methodImpl declared above
})
// INITIALIZATION
dataObj = {
title: 'Holiday',
author: 'Stanley Middleton',
age: 45
}
// INITIALIZATION
methodsObj = {
method1: methodImpl
}
app.mount('#app')
Now consider that same code, but replace methods: {method1: methodImpl}
with methods: methodsObj
:
// ? HOISTED DECLARATIONS
var dataObj = undefined;
function dataFunction (){
return dataObj
}
var methodsObj = undefined;
function methodImpl (){
this.title = 'Infinite Jest'
}
// ? HOISTED DECLARATIONS
const app = Vue.createApp({
data: dataFunction,
methods: methodsObj // ? methodsObj undefined above, so method1 would be undefined in the app
})
// INITIALIZATION
dataObj = {
title: 'Holiday',
author: 'Stanley Middleton',
age: 45
}
// INITIALIZATION
methodsObj = {
method1: methodImpl
}
app.mount('#app')
The issue with methodsObj
in the example above can be fixed by declaring and initializing it before usage (which is generally a best practice):
// declare and initialize vars here...
var dataObj = {
title: 'Holiday',
author: 'Stanley Middleton',
age: 45
}
function dataFunction (){
return dataObj
}
var methodsObj = {
method1: methodImpl
}
function methodImpl (){
this.title = 'Infinite Jest'
}
// now, use the declarations from above
const app = Vue.createApp({
data: dataFunction,
methods: methodsObj
})
app.mount('#app')
And here's the visualization of the hoisting above:
// ? HOISTED DECLARATIONS
var dataObj = undefined;
function dataFunction (){
return dataObj
}
var methodsObj = undefined;
function methodImpl (){
this.title = 'Infinite Jest'
}
// ? HOISTED DECLARATIONS
// INITIALIZATION
dataObj = {
title: 'Holiday',
author: 'Stanley Middleton',
age: 45
}
// INITIALIZATION
methodsObj = {
method1: methodImpl
}
const app = Vue.createApp({
data: dataFunction,
methods: methodsObj // ? methodsObj declared and initialized above
})
app.mount('#app')
One of the motivations of const
and let
(introduced in ES2015) was to avoid common bugs from var
hoisting, such as you observed above. If you had used const
/let
instead of var
in your original code, the compiler would've thrown an error, which might've signaled to you then that the declaration should be moved above the usage. Consider using a linter that discourages the use of var
.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 |