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

Angular2: The NgFor directive is designed to work with Iterables like Arrays for data binding

I'm currently working on a university project to develop a web application consisting of a Web API and a Frontend that interacts with the API. The specific focus of this project is a recipe website. Although I have limited experience with technologies ...

Perhaps dividing numbers with regular expressions

My HTML textarea allows users to input numeric serial numbers in various formats - either inline, separated by any character, or in columns from an Excel file. The serial codes are either 14 characters long if the first character is "1," or always 15 char ...

The Vue watcher will only be triggered when both parameters are present, rather than just one

Imagine a scenario where there is a childComponent and a parentComponent involved. In this case, the parentComponent passes a 'sections' prop to the childComponent. Initially, the default state of the 'sections' prop in the parentComp ...

Unable to connect with controller after deploying asp.net mvc ajax call on server

For the first time, I am encountering a new issue. Although my code runs smoothly on my localhost, when I upload it to the server, I get a bad request error. The specific error message is: 400 (Bad Request) Below is the snippet of my code: Controll ...

Using a button click to toggle the vue-ctk-date-time-picker in VueJS

Currently, I am utilizing the Vue component - https://github.com/chronotruck/vue-ctk-date-time-picker within my own component. However, I am encountering an issue where I would like to maintain the component's original functionality while having a but ...

Is there a way to place two input fields from different forms side by side on the same line?

Here are two forms extracted from an html page: <form method="get" action="search/s" id="number"> <div style="text-align: center;"> <input type="text" id="regNo" name="regNo" size="30" maxLength="50" > or ...

Detecting single letters in a sentence and changing their appearance using CSS

Looking to make a subtle change to text? I need to swap out single letters in a passage (I have a cat that ate a fish). Any ideas on how to do this? The goal is to input a block of text into a textbox, then display it in a div. I've had difficulty fi ...

What is the best way to divide a GraphQL schema to avoid circular dependencies?

I have a question that is similar to the issue of circular dependency in GraphQL code discussed on Stack Overflow, but my problem lies within JavaScript (ES6). The size of my schema definition has become too large, and I am struggling to find a way to bre ...

Issue with md-stretch-tabs in Angular-Material causing a problem

I am in the process of developing an Angular-based application. ISSUE: I included md-stretch-tabs in my md-tabs element, but when I switch to tab#2, the tab retracts as if there is not enough space to flex. Is this problem related to dependencies or the c ...

Passing the contents of a datatable as parameters to a PHP script

I am facing a challenge with my datatable that has two columns, "Name" and "Age". After populating the datatable using Ajax, I create a button for each row. The goal is to send the "Name" and "Age" fields of the clicked row to a PHP script, which will then ...

Tips for organizing JSON object data and displaying it appropriately on an HTML page

This code utilizes ajax: $("form").on("submit", function () { var data = { "action": "test" }; data = $(this).serialize() + "&" + $.param(data); $.ajax({ type: "POST", dataType: "json", url: "ajax2.php" ...

In the event that the "li" element contains an "

<ul> <li> <ul></ul> </li> <li></li> <li></li> <li></li> <li> <ul></ul> </li> </ul> Is there a way to specifically a ...

Combining td elements within a table

Currently, I am working on creating a weekly calendar using a combination of JavaScript and PHP to interact with an SQL table. The process involves generating an empty table structure in JavaScript and then populating specific cells with data retrieved fro ...

Selenium encountered an error when trying to execute the 'querySelector' function on the document. The selector provided, my_selector, is not recognized as a valid selector

Whenever I run this code: document.querySelector(my_selector) using selenium, an error is thrown: Failed to execute 'querySelector' on 'Document' my_selector is not a valid selector my_selector is definitely a valid selector that func ...

Express.js code is experiencing difficulties with autocomplete functionalities

jQuery autocomplete code example [Express JS code for retrieving data][2\ Example of fetching data in Express JS ...

Pass data to all routes in ExpressJS

After logging in, I am setting req.session variables as follows: req.session.loggedin = true req.session.firstname = loginDetails.firstName; I would like to streamline this process and pass this information to ALL routes without manually adding them to ea ...

Enhance a DOM element using personalized functions in jQuery

Seeking advice on how to create custom widget placeholders with a "setvalue" function specific to each type of widget: $.fn.extend($(".dial"), { setval: function(val) { }); Attempting to avoid extending jQuery.fn directly since different widget type ...

What strategies can I implement to integrate Cordova with a combination of Meteor and React?

I'm currently struggling to implement a Cordova plugin with Meteor and React. According to the documentation: You should wrap any functionality that relies on a Cordova plugin inside a Meteor.startup() block to ensure that the plugin has been fully ...

What is the best way to create a floating navigation bar that appears when I tap on an icon?

As a beginner in the realm of React, I recently explored a tutorial on creating a navigation bar. Following the guidance, I successfully implemented a sidebar-style navbar that appears when the menu icon is clicked for smaller screen sizes. To hide it, I u ...

Retrieving various properties of an object by matching IDs and displaying them without repeated reductions

I'm interested in finding a more efficient way to retrieve properties from a reduced object within a Vue component or wrapper DOM element. Let's say I have these two data objects in my component: player: [{ active: true, id: 0, name: &q ...