Vue JS: dynamic reactive structure

As I delved into understanding the basics of reactivity and its syntax, I encountered an interesting problem. Take a look at this code 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')

with the corresponding HTML structure:

<div id="app">
        [...]
        <div @click="method1">change book title</div>
</div>

This code functions correctly and I successfully separated data using a function and object. However, I am facing some challenges with extracting method. Is it possible to achieve similar separation for methods? Using methods: methodsObj in the createApp initialization does not seem to work. Can you suggest a way to make it work? I understand that this may be more of an academic exercise, but it helps me grasp the syntax and relations between objects better.

Answer №1

While working with JavaScript, it's important to understand the concept of hoisting. Var variables are hoisted to the top, but their initializations do not move along. On the other hand, functions and their definitions are also hoisted. Relying heavily on hoisting in your code can lead to potential issues.

Let's visualize how hoisting works in your original functioning 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 is declared above
})
// INITIALIZATION
dataObj = {
    title: 'Holiday',
    author: 'Stanley Middleton',
    age: 45
}
// INITIALIZATION
methodsObj = {
    method1:  methodImpl
}

app.mount('#app')

Now, let's revisit the 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 was not defined earlier, hence method1 would be undefined in the app
})
// INITIALIZATION
dataObj = {
    title: 'Holiday',
    author: 'Stanley Middleton',
    age: 45
}
// INITIALIZATION
methodsObj = {
    method1:  methodImpl
}

app.mount('#app')

To resolve the issue with methodsObj, it is recommended to declare and initialize it before using it:

// 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')

Here's a visualization to illustrate the hoisting process:

// 👇 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 is declared and initialized previously
})

app.mount('#app')

Check out the demo here

An important enhancement brought by ES2015 was the introduction of const and let keywords to address common bugs associated with hoisting like the one observed above. Consider replacing var with const/let to prevent such issues in your codebase, and utilize a linter that discourages the usage of var.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Challenges encountered when creating routes in Reactjs

I'm currently working on a project and facing some challenges with managing routes. My frontend is split into two sections: one for the client side and the other for the admin panel, which is responsible for managing the client side. For example, if I ...

Using an if statement within a map function in a React component

I am facing a challenge with using an if statement inside a map function without changing the return value. Here is my code snippet: this.example = this.state.data.map((item) => { return( <div> {if(1 + 1 == 2){ dat ...

Why isn't the Nunjucks extends directive functioning when the template is stored in a different directory and being used

I have successfully integrated nunjucks templating into my express app. Below is the directory structure of my project: . nunjucks-project |__ api |__ node_modules |__ views |__ templates |__ layouts |__ default.html ...

Encountered an unforeseen token "<" that is causing the server to return a 404 HTML page instead of the intended .js

I am currently developing a to-do list application using Node.js Express and EJS. In the app, I have implemented a filtering functionality with a URL path of "/filter/query". Based on the selected category (either "lists" or "lastupdated"), the app filters ...

Discovering the art of line breaks

Imagine I have a random block of text displayed in a single line, like this: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Due to various reasons such as width settings or text-zoom, the text may display as two or more lines on the viewer&apos ...

The canvas's document.getElementById function is unable to find any matching element,

Hello everyone, I am currently diving into the world of javascript and trying to expand my knowledge. However, I have encountered a problem that has me stumped, and I could really use some assistance. While exploring, I came across this page: http://www.w ...

Ways to retrieve the most recent message on WhatsApp Web

I'm currently developing a JavaScript script for WhatsApp Web that will automate responses to messages in a specific group. Here is a snippet of my code: console.log('WhatsappWeb On'); function sleep(num){ setTimeout(num); } var eve ...

Is there a way to use moment js to change the date format to just show the month and year?

Want to transform the date time format using momentjs 2017-02-01T00:00:00.000Z into 02-2017 ( month-year ) Looking for a way to change the date format to display only month-year using momentjs? I attempted it like this: var MnthYr = moment(2017-02-01 ...

Passing parameters with AngularJS can return as Resteasy @FormParam being null

Struggling to integrate AngularJS on the front end with Resteasy as my Rest API. The issue I'm encountering is that my @FormParam values are always null when sending parameters using AngularJS. Below is a snippet of my JavaScript code: $scope.addPe ...

What could be the reason for angularjs not functioning as expected?

After attempting to create a basic JavaScript unit test using angular.js, I encountered failure without understanding the reason behind it. test.html <html> <head> <script src="angular-1.2.21/angular-scenario.js" ng-autotest></ ...

Adding local JavaScript to a Vue component is a great way to enhance its functionality

I am currently working on integrating a homepage concept (Home.vue) into my project. The design is based on a template that I purchased, which includes CSS, HTML files, and custom JavaScript. While most of the CSS has been successfully imported, I am havin ...

What is the widely used term for the container that allows for panning by dragging with a mouse?

I am looking to design a container that extends beyond the width of the page, allowing users to pan by dragging through empty space between controls without zooming in or out. What is this type of container control typically referred to as? I am intereste ...

After toggling the switch to send the current state to the server, the React state remained unchanged

Could you clarify why the relay1 state is being sent as false? Why doesn't handleControlRelay1 change the state? Am I making a mistake by placing this inside a function? setRelay1((prevValue) => !prevValue); // ... const [relaysData, setRelaysD ...

Tips on adding TypeScript annotations to an already existing global function

I'm contemplating enhancing an existing project by incorporating TypeScript type annotations. Struggling to supply an external declaration file for a straightforward example: app.ts: /// <reference path="types.d.ts"/> function welcome (person ...

Understanding the fundamental concepts of callbacks with Backbone.js

Currently, I am working with Backbone to send a login form to my server. Once the form is submitted and the database query is successful, a boolean value is flipped to enable GET responses from the server. However, the issue arises when it attempts to fetc ...

Remove the initial DIV element from the HTML code

I have created a unique chat interface by combining JScript, php, and jquery. The chat messages are saved in an HTML document that gets displayed in the text area. Each user input message is contained within its individual div tag: <div>Message</ ...

Guide on incorporating a Python script into a website using DJango

I am new to Django and looking for guidance. My goal is to have users input text in an HTML textbox, then process that text using Python and display it on the website. Despite going through documentation and tutorials, I have not been successful in gettin ...

Unlocking app data properties in Vue 3: A comprehensive guide

I am currently in the process of transitioning to Vue 3. In my previous Vue 2 app, I could access properties like this: import { createApp } from 'vue/dist/vue.esm-bundler'; ... const app = createApp({ // el: 'app', // removed data ...

Generating JSON data from a dropdown menu element

I'm working on a web page that showcases information for students in my database. One key field is their birth country, currently stored as the full name of the country. My goal is to convert these full country names into two-character strings. For ex ...

Modifying the CSS class of an element does not produce the desired effect after altering its styles using JavaScript

html: <input id="myinput" class="cinput" type="image" src="http://www.foodwater.org.au/images/triple-spiral-3-small-button.jpg"/> <br><br><br><br> <button id="s">set to visible class</button> <button id="h"> ...