Need to import Vue component TWICE

My question is simple: why do I need to import the components twice in the code below for it to function properly?

In my current restricted environment, I am unable to utilize Webpack, .vue Single File Components, or npm. Despite these limitations, I managed to piece together a functioning Vue app using TypeScript files. However, I am puzzled by the necessity of importing the component file and then requiring it as a component.

This setup may not be ideal, especially since we plan to deploy this as a Proof of Concept with developers who are also new to Vue. Therefore, I would like to improve this process and avoid introducing bad practices from the beginning.

index.ts

import * as Vue from "vue";
import * as Apple from "./App";                 
Vue.component('apple2', Apple.default);          

let v = new Vue({
el: "#app",
components: { Apple},                           
template: `
<div>
    <apple2/>                                   
</div>`,
data: {
    name: "World"
},

});

App.ts

import * as  Vue from "vue";
import * as fred from  "./Hello";                   
Vue.component('fred2', fred.default);                

export default Vue.extend({
name: 'Apple',
template: `
<div>
    <fred2 :name="name" :initialEnthusiasm="4"/>     
</div>`,
data() {
    return { name: "World" }
},
components: { fred }                                 
});

Index.html

<!doctype html>
<html>
<head>
  <script src="scripts/vue.min.js"></script>
  <script data-main="scripts/build/index" src="scripts/lib/require.min.js"> 
  </script></head>
   <body>
     <div id="app"></div>
   </body>

tsConfig

{"compileOnSave": true,
"compilerOptions": {
"module": "amd",
"moduleResolution": "node",
"noImplicitAny": true,
"noEmitOnError": false,
"outDir": "./scripts/build",
"removeComments": false,
"sourceMap": true,
"target": "es5",
"allowSyntheticDefaultImports": true,
"esModuleInterop": true
},
"exclude": [
"node_modules",
"wwwroot"
],
"include": [
"./scripts/**/*"
]

}

Answer №1

When you write this code snippet:

Vue.component('apple2', Apple.default);

You are essentially associating the component definition object (Apple.default) with the name apple2 in the global Vue instance, allowing all components rendered by that Vue instance to access it. To simplify your code in index.ts, you can remove the following section:

components: { Apple}

Your app should still function correctly in theory.

However, if you utilize TypeScript, you have the option to structure your app as if it were using a module system. This enables you to import sub-components into each parent component, like so:

App.ts

export default const component = {
    template: '<div>My component</div>'
}

index.ts

import Vue from 'vue';
import component from './App';

new Vue({
    el: '#app',
    components: {
        'my-imported-component': component
    }
});

Within your template:

<div id="app">
    <my-imported-component/>
</div>

This approach may be more favorable as it avoids cluttering the global Vue instance with numerous components. Ultimately, the choice between methods depends on personal preference and the requirements of your project.

For further details, refer to the following link:
https://v2.vuejs.org/v2/guide/components-registration.html

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

JavaScript alert box

I'm fairly new to the world of web development, with knowledge in CSS & HTML and currently learning TypeScript. I'm attempting to create a message icon that opens and closes a notifications bar. Here's where I'm at so far: document.getE ...

Leveraging the OpenLayers Map functionality within an Angular service

I am curious to learn if there is a way to utilize a service in Angular for creating an OpenLayers map and then passing that service to other components to update the map based on interactions within those components. I have outlined my approach below. Des ...

Misunderstanding the concept of always being right

Here is a code snippet that raises an error in TypeScript: class Status { constructor(public content: string){} } class Visitor { private status: Status | undefined = undefined; visit(tree: Tree) { if (tree.value > 7) { this.status = new ...

Specifying the return type of a function as a combination of the types of the input arguments

Is there a way to safely implement the given function in TypeScript without using unsafe casts or an extensive number of function overloads with various input permutations? interface Wrapped<T> { type: string; data: T; } interface WrappedA&l ...

Exploring deeply nested directories using the ContentNavigation component in Nuxt 3 framework

Within my content folder lies a directory named planets, housing yaml files for various planets. My goal is to display these planet pages as navigation items using the content navigation component. Currently, I am only able to obtain a link to the /plane ...

Unique component for customized form controls

Currently, I am delving into the world of Angular. One challenge I have been tackling is creating a custom form control that includes a mat-select. The goal is for the submitted form value to be the item selected in the dropdown. After sifting through num ...

Troubleshooting Missing Exports from Local Modules in React Vite (Transitioning from Create React App)

I have encountered an issue while trying to import exported members from local nodejs packages in my project. Everything was working fine with the standard CRA webpack setup, but after switching to Vite, I started getting the following error: Unca ...

RxJS emits an array of strings with a one second interval between each emission

Currently, my code is set up to transform an Observable<string[]> into an Observable<string>, emitting the values one second apart from each other. It's like a message ticker on a website. Here's how it works at the moment: const ...

What is the most effective way to implement a single modal throughout my web application without having to duplicate HTML code on each page?

After realizing I was repetitively adding the same div to every page for a modal dialog, I decided to place a single div in the site.master page and call it when needed. This method worked fine until I began implementing ajax with partial page updates. H ...

Handling a change event for a mat-datepicker in Angular 7 can be tricky, especially when its value is tied to an optional input parameter. Let's dive into how to

I've recently started working with angular development and encountered a challenge with a mat-datepicker. The value of the datepicker is connected to filterDate using [(ngModel)] as an @Input() parameter. I have implemented a handleChange event that e ...

Transfer the filteredWorkers property from the data section to the computed section in Vue.js

Can you please assist me with this task? I need to move the property filteredWorkers and fields to computed properties. As you can see below, I am using b-table from Bootstrap and multiselect from vue.material. I'm not sure of the best approach to ac ...

Warning: Vuex store state should only be mutated within mutation handlers. If mutations are attempted outside of Vuex, an error will be triggered

In my Vuex mutation, I set an error message and use a setTimeout function to clear it after 5 seconds. This is how I implement it: setError(state, error) { state.error = error setTimeout(() => { state.error = null }, 5000) }, When h ...

I'm experiencing an issue with my website where it appears broken when I build it, but functions properly when I use npm run dev in Next

For my project, I have utilized NextJs, Tailwind, React, and Typescript. It is all set and ready to be hosted. After using "output: export" in next.config.js and running npm run build, the process was successful. However, when viewing my website locally, I ...

What is the best approach for managing the Paste event (using Ctrl+v or mouse) in vue.js?

When content is pasted into a text area in my vue.js application, I would like to trigger a function. Which event should I use for this scenario? ...

Creating a map-like scrolling feature for a full-sized image, allowing both horizontal and vertical movement

My goal is to create an infographic image that can be scrolled horizontally and vertically, zoomed in or out, and where I can add markers just like Google Maps. I attempted the solution of using two scroll views as suggested here: https://github.com/faceb ...

What is the best way to rid ourselves of unwanted values?

In the laravel-vue-boilerplate package, there is a User CRUD feature. I duplicated this functionality to create an Item CRUD by making some changes and adjustments. Everything is working fine except for one issue: after editing an item, when trying to add ...

Executing Promises in a loop: TypeScript & Angular with IndexedDB

Currently, I am working on a data synchronization service where data is being retrieved from a web service and then stored in IndexedDB. In my TypeScript Angular Service, the code looks something like this: this.http .post(postUrl, postData) .suc ...

Unable to resolve all parameters for the RouterUtilities class

My goal is to develop a RouterUtilities class that extends Angular's Router. Despite the app running and compiling smoothly, when I run ng build --prod, it throws an error message like this: ERROR in : Can't resolve all parameters for RouterUtil ...

Utilizing external JavaScript libraries in Typescript for integration with nodeJS

We've recently made the switch to using Typescript + Electron for developing a browser-based desktop application. However, we often encounter delays when loading external Javascript libraries. While typings helps with most of our needs, there are stil ...

Can you explain how to invoke a class with express().use function?

Currently, I am delving into learning Node JS with TypeScript but have hit a roadblock with a particular issue. In my app.ts file, I have initialized the express and attempted to call the router class inside the app.use() method, only to encounter an error ...