javascript - 使用 vue-router 给出 "Cannot find element #app"和 "TypeError: Cannot read property ' matched' of undefined"错误

标签 javascript vue.js vue-router

我正在尝试使用 Vue.js 重新创建我之前使用 Scala Play 制作的前端应用程序(我想了解有关基于组件的网页设计的更多信息)。

我制作的第一个页面的所有内容都加载得很好,但我想实现路由,这样我就可以拥有多个页面(而不是只有一个大型单页应用程序)。我使用 npm install vue-router --save 安装了 vue-router,并尝试遵循以下教程(使用我已经制作的组件):https://scotch.io/tutorials/how-to-build-a-simple-single-page-application-using-vue-2-part-1 .

据我所知,所有内容应该都能顺利加载,但没有加载任何内容,我收到以下控制台错误:

[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)

我没有粘贴完整的堆栈跟踪,但如果需要可以粘贴。

我的代码如下:

ma​​in.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>

组件/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>

如果我还需要包含 Header.vue 和 Posts.vue,请告诉我 - 我省略了它们,因为在我尝试使用 vue-router 之前它们渲染得很好。

如何消除这些控制台错误,以便在使用 vue-router 时正确呈现我的主页?我四处搜索,到目前为止,我所有的搜索结果都让我对“确保 router 是小写字母”(确实如此)、“确保 routes是小写字母”(它是),以及“使用 import Vue from 'vue/dist/vue.js'”(没有用)。

最佳答案

关于原问题:

我相信您从评论讨论中知道,错误 [Vue warn]: Cannot find element: #app是因为两个 Vue 实例被配置为一个接一个地挂载在同一个根 DOM 节点 #app .

第一个 Vue 实例挂载,在这样做的过程中,用在它自己的模板中定义的 HTML 替换根 DOM 节点。因此,#app根 DOM 节点不存在,第二个 Vue 实例挂载失败,因为它找不到任何 id 为 #app 的 DOM 节点.

这意味着如果第一个 Vue 模板包含一个 ID 为 #app 的 DOM 节点,第二个 Vue 实例可能会安装在那里,用它自己的替换第一个实例中的任何现有 HTML。

通过删除重复的 Vue 实例解决此错误。


关于您的后续问题:

I don't have the faintest idea why this works without all the el: '#app', template: '<App/>', components: { App }

首先要注意的是 Vue 实例属性 vm.$el 和 Vue 实例方法 vm.$mount() 在大多数情况下它们在功能上是等效的——每个都允许您指定将安装 Vue 实例的根 DOM 元素。

主要区别在于它们的应用:

  • 您使用 vm.$el在实例创建时声明根 DOM 节点。但是,提供值不是强制性的,如果您不这样做,实例将以未安装状态创建。

  • vm.$mount()允许您在实例化后为未安装的实例指定根 DOM 节点。

如文档中所述:

If a Vue instance didn’t receive the el option at instantiation, it will be in “unmounted” state, without an associated DOM element. vm.$mount() can be used to manually start the mounting of an unmounted Vue instance.

当然,如果你使用vm.$mount()而不是 vm.$el在创建实例时,这在很大程度上取决于开发人员的品味(尽管 $mount() 也接受各种输入,因此存在其他细微差别)。但是从你的问题的 Angular 来看,没有实际的区别。

最后,Vue 的 template属性(property)和render()方法只是定义 Vue 实例模板结构的两种策略:

  • template是更高级别的模板抽象,允许您定义一个字符串模板;例如:<div><App/></div> Vue 将其解析为一个结构,根据需要实例化任何子组件。

  • render()是另一种较低级别的模板抽象,它是 closer-to-the-compiler alternative to templates .它对于细粒度/编程用例或与其他模板语言(如 JSX 或原始 JS)一起使用更加灵活。

您的示例中的主要明显区别是 template使用 <App/> 定义字符串模板成分。 Vue 实例需要在解析这个模板字符串之前知道这个组件是什么,所以它必须被声明为一个组件。

然而,render()允许 App直接传递给渲染的组件,因此不需要定义 template属性或声明任何组件。

我的观点是,前者更明确——这不是坏事——并且在声明具有多个组件的结构时更具声明性和可读性。为此,Vue 似乎建议在大多数情况下使用模板字符串。也就是说,后一种方法也可以很简洁,并且您经常会在安装单个顶级入口点组件(例如:App)的地方看到它。

另一个(隐含的)策略是DOM 模板。在没有 template 的情况下属性(property)或render()方法,使用在根 DOM 节点内定义的 HTML 结构——尽管通常不鼓励这样做。

希望这有帮助:)

关于javascript - 使用 vue-router 给出 "Cannot find element #app"和 "TypeError: Cannot read property ' matched' of undefined"错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54735471/

相关文章:

javascript - jQueryUI : restrict container height on drag and drop element

javascript - 使用 nuxt-link 在链接中传递 id 号

vue.js - 在作用域插槽内使用 v-model

vue.js - vue-router 和数据属性的理解

javascript - 如何在加载惰性加载的路由组件时显示 "loading"动画?

javascript 从缓冲区将图像绘制到 html (nodejs/socket.io)

javascript - AngularJS 按字母数字顺序列出项目

javascript - jQuery (window).load 页面加载后?

javascript - 在 Vuejs 中使图片可点击

javascript - Vue router 不会重新初始化子组件