Encountering errors like "Cannot find element #app" and "TypeError: Cannot read property 'matched' of undefined" typically happens when using vue-router

Recently, I decided to dive into Vue.js as a way to revamp an existing frontend app that was originally built using Scala Play. My goal is to explore the world of component-based web design and enhance my skills in this area.

Initially, everything seemed to be loading smoothly on the first page I created. However, I wanted to take things a step further by implementing routing to enable multiple pages instead of just being confined to a single-page application. To achieve this, I installed vue-router through npm install vue-router --save and started following a tutorial that aligns with my vision: https://scotch.io/tutorials/how-to-build-a-simple-single-page-application-using-vue-2-part-1.

Despite what should have been a smooth transition, I encountered some obstacles along the way. Whenever I tried to load the components, nothing appeared on the screen, and a series of console errors greeted me:

[Vue warn]: Cannot find element: #app
[Vue warn]: Cannot find element: #app
[Vue warn]: Error in render: "TypeError: Cannot read property 'matched' of undefined"

found in

---> <App> at src/App.vue
       <Root>

TypeError: Cannot read property 'matched' of undefined
    at render (vue-router.esm.js?8c4f:76)
    at createFunctionalComponent (vue.runtime.esm.js?2b0e:3033)
    .... (etc)

I haven't included the full stack traces here, but I can provide them if necessary.

This is the snippet of code involved:

main.js

import Vue from 'vue'
import App from './App.vue'
import VueRouter from 'vue-router'

import Home from './components/Home.vue'

Vue.use(VueRouter)

const routes = [
  { path: '/', component: Home }
]

const router = new VueRouter({
  routes
})

new Vue({
  el: '#app',
  template: '<App/>',
  components: { App },
  router
}).$mount('#app')

Vue.config.productionTip = false

new Vue({
  render: h => h(App),
}).$mount('#app')

App.vue

<template>
  <div>
    <router-view></router-view>
  </div>
</template>

<script>

export default {
  name: 'app'
}
</script>

<style>
  * {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
  }
  body {
    font-family: Arial, Helvetica, sans-serif;
    line-height: 1.4;
    background-color: aliceblue;
  }
</style>

components/Home.vue

<template>
  <div id="app">
    <Header />
    <Posts v-bind:posts="posts" />
  </div>
</template>

<script>

import Posts from './Posts.vue'
import Header from './Header.vue'

export default {
  name: 'home',
  components: {
    Header, Posts
  },
  data() {
    return {
      posts: []
    }
  }
}
</script>

<style>
</style>

If you think it's necessary, I can also include Header.vue and Posts.vue; initially, they were rendering without issues before I introduced vue-router into the picture.

Any insights or suggestions on how to resolve these persistent console errors are highly appreciated. I've scoured numerous resources and forums, all pointing towards basic troubleshooting steps like ensuring lowercase usage for router and routes, as well as attempting different import techniques such as

import Vue from 'vue/dist/vue.js'
(unsuccessful).

Answer №1

When it comes to the initial issue:

As discussed in the comments, the errors

[Vue warn]: Cannot find element: #app
occurred because two Vue instances were set up to mount consecutively on the same root DOM node #app.

The first Vue instance mounts and replaces the root DOM node with its defined HTML template. Consequently, the original #app root DOM node is no longer present, causing the second Vue instance to fail in mounting as it cannot locate any DOM node with id #app.

This suggests that if the initial Vue template contained a DOM node with id #app, the second Vue instance would likely mount there by replacing any existing content from the first instance.

To resolve this error, the duplicate Vue instance should be removed.


I don't understand why this works without all the

el: '#app', template: '<App/>', components: { App }

The key thing to note is that Vue instance property vm.$el and Vue instance method vm.$mount() are essentially interchangeable—both allow you to specify the root DOM element for mounting the Vue instance.

The main distinction lies in their use:

  • You utilize vm.$el to designate the root DOM node during instance creation. While providing a value is not mandatory, leaving it empty results in an instance being in an unmounted state.

  • vm.$mount() enables you to specify a root DOM node for an unmounted instance post instantiation.

If a Vue instance wasn't provided with the el option upon instantiation, it remains "unmounted," lacking an associated DOM element. vm.$mount() can be utilized to manually commence the mounting process of an unmounted Vue instance.

vm.$mount() or vm.$el during instance creation usually boils down to personal preference. However, there may be other subtle variances since $mount() accepts various inputs. But in the context of your inquiry, there isn't a significant practical difference.

template property and render() method are both approaches for defining the template structure of a Vue instance:

  • template gives you a higher-level template abstraction where you define a string template; e.g.,

    <div><App/></div>
    , which Vue interprets and instantiates child components as necessary.

  • render() serves as a lower-level alternative, closer to the compiler compared to templates. It offers more flexibility for fine-grained or programmatic scenarios, including working with other template languages like JSX or raw JS.

template specifies a string template using the <App/> component. The Vue instance must know about this component before parsing the template string, requiring it to be declared as a component.

render() allows direct rendering of the App component without needing to declare a template property or any components. This approach may seem less verbose when mounting a single, top-level entry-point component like App.

Another implicit strategy is the DOM template. In the absence of a template property or render() method, the HTML structure within the root DOM node is utilized—though generally discouraged.

Answer №2

To resolve the issue, I streamlined my main.js file by including only one section for new Vue. Here is how it looks now:

new Vue({
  router,
  render: h => h(App)
}).$mount('#app')

Although I am unsure why this solution works without including the

el: '#app', template: '<App/>', components: { App }
declarations, I would appreciate an explanation. I hesitated to provide an answer because I do not fully comprehend why this approach was successful. If someone can offer an explanation, I am willing to accept that explanation in a revised answer (feel free to edit my response accordingly).

Answer №3

The problem that I discovered was possibly due to the absence of

<div id="app"></div>

in the main content of your index.html file.

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

Utilizing the Global Module in NestJs: A Step-by-Step Guide

My current project is built using NestJS for the back-end. I recently discovered that in NestJS, we have the ability to create Global Modules. Here is an example of how my global module is structured: //Module import {Global, Module} from "@nestjs/commo ...

Trouble with pinch zoom functionality in a Vue component

I have a Vue component that allows me to zoom in on an image using the mouse wheel, but I'm experiencing strange behavior with pinch zoom. When I place two fingers far apart on the screen, it zooms in significantly, and when I bring them closer togeth ...

Issues with the webpack-dev-server and React

I was just reading up on Webpack and the moment came for me to start using it, but I ran into an error. npm ERR! code ELIFECYCLE npm ERR! errno 1 npm ERR! <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="6a09180b471e1f1e ...

The Express Generator is having trouble detecting the routes within the users file when using app.use('/login', users)

Having used the express generator, I am facing confusion regarding why I cannot utilize the users.js routes file for my login routes. I have created the POST route below, and when I keep it in app.js, everything works smoothly. However, if I attempt to mo ...

Transmit information to the client-side webpage using Node.js

One of the main reasons I am diving into learning Node.js is because I am intrigued by the concept of having the server send data to the client without the need for constant querying from the client side. While it seems achievable with IM web services, my ...

The title attribute in Vue3 is updated through props, but computed properties remain unaffected

I incorporated an external library into my project using Vue3. The component I am utilizing is sourced from a third-party library [Edit: Upon realizing that the GitHub repository for this library is no longer being maintained, I have updated the code to re ...

Initiating, halting, and rejuvenating a timer in JavaScript

Here is a simple code snippet where I'm experimenting with starting, stopping, and resetting a JavaScript timer. The goal is to have a timer running on a page that sends a message once it reaches the end of its countdown before restarting. The stop b ...

Looping through a collection of data in Vue.js and dynamically generating labels for input

Is there a way to ensure the input id and label for are unique for repeated input elements while using Vue.js v2? <section class="section" v-for="(section, i) in sections"> <div class="fields"> <fieldset> <inp ...

Troubleshooting the cancellation of Laravel API requests sent from Vue

I've been facing an issue while trying to send formData from Vue using Axios to a Laravel (v6) API on Laravel Homestead. The formData includes some data and an Excel file for reading and validating data in the backend. Surprisingly, everything works f ...

Create a vibrant PNG image background that changes dynamically based on the dominant color of the

Is it possible to dynamically set the background color of a PNG image, either white or black, based on the dominant color in the image? For example, this image should have a dark background: https://i.stack.imgur.com/cerjn.png And this one should have a ...

Exploring how to use React with a select component featuring objects

Hello, I am new to working with React and I have a question regarding the select component of Material UI. Here's my situation: I am creating functionality for creating and editing a User object. This User object has a primary key and some data, incl ...

The ng-view directive appears to be missing in the AngularJS framework

I am attempting to create a route using AngularJS, but when I launch my application, the ng-view does not display anything. I am new to AngularJS. index : <!DOCTYPE html> <html lang="en"> <head> <title>CRUD</title> </ ...

How can I disable the 'Leave site?' dialog box for Google Forms embedded in an iframe?

Within my Vue component, I have integrated Google Forms using an iframe. However, a challenge arises when users attempt to navigate to another page and are prompted with the 'Leave site? Changes that you made may not be saved' dialog. Is there a ...

Access the OpenWeatherMap API to retrieve the weather forecast for a single time slot within a 5-day period

Utilizing the openweathermap api, I am retrieving a 5-day/3-hour forecast here. The API call provides multiple results for each day with data available every 3 hours. For the full JSON response, you can access it here. Please note that the API key is only ...

I am currently facing an issue with retrieving the class value that is being generated by PHP code

I am currently facing an issue with jQuery and PHP. Whenever I attempt to target the click event on the class ".id_annonce" in the dynamically generated PHP code, it doesn't retrieve the exact value of what I clicked. Instead, it always gives me a fi ...

How to programmatically unselect an ng-checkbox in AngularJS when it is removed from an array

Utilizing checkboxes to gather values and store them in an array for dataset filtering purposes. The objectives are as follows: Show child filters when parent category is selected. Unselect all children if parent is unselected (otherwise they will ...

Drop draggable items on top of each other

I'm wondering if there's a way to drag jQuery elements into each other. To illustrate my question, I've duplicated this code (link) and made some style changes. Here is the updated version: Fiddle Link. In the current setup, you can drag e ...

Creating effective href anchors within an iframe using the `srcdoc` attribute

While loading some HTML content in an iframe using the srcdoc attribute, I encountered an issue where following anchor tag links inside the iframe caused the entire page to load within the iframe instead of scrolling to the linked id. You can see a demons ...

Extract the element when the mouse is clicked

I'm currently working on developing a Chrome extension with a specific goal in mind: My aim is to capture the username when a user Ctrl-clicks on a username while browsing Reddit, and then transfer that username from the content script page to the ba ...

Using a Vue computed method to compare elements in two separate arrays

Presently, I am utilizing Vue v2.x.x and dealing with an array: sectionTitles = ['Technology', 'Data', 'Poverty and Research', ...] Additionally, I have jobsData structured like this: [{'title': 'Software Engin ...