Использование vue-router приводит к ошибкам «Cannot find element #app» и «TypeError: Невозможно прочитать свойство« совпало »с неопределенными» - PullRequest
0 голосов
/ 17 февраля 2019

Я пытаюсь использовать Vue.js, чтобы воссоздать приложение, созданное ранее с помощью Scala Play (я хотел бы узнать больше о компонентном веб-дизайне).

У меня все нормально загружалосьпервую страницу, которую я сделал, но я хотел реализовать маршрутизацию, чтобы у меня было несколько страниц (а не просто одно большое одностраничное приложение).Я установил vue-router, используя npm install vue-router --save, и пытаюсь следовать следующему руководству (используя компоненты, которые я уже сделал): 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)

Я не вставил полные трассировки стека, но могу выполнить при необходимости.

Myкод ниже:

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>

компоненты/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' "(не работает).

Ответы [ 3 ]

0 голосов
/ 19 февраля 2019

Что касается исходной проблемы:

Как я уверен, вы знаете из обсуждения комментариев, ошибки [Vue warn]: Cannot find element: #app были вызваны тем, что два экземпляра Vue были настроены для монтирования - один за другим - одновременнокорневой узел DOM #app.

Первый экземпляр Vue монтируется, и при этом заменяет корневой узел DOM на HTML, определенный в его собственном шаблоне.Поэтому корневой узел DOM #app больше не существует, а второй экземпляр Vue не удается подключить, поскольку он не может найти ни один узел DOM с идентификатором #app.

Это означает, что если первый Vueшаблон включает в себя узел DOM с идентификатором #app, второй экземпляр Vue, вероятно, будет там монтироваться, заменяя любой существующий HTML из первого экземпляра своим собственным.

Эта ошибка устраняется путем удаления дубликата Vueinstance.


Относительно вашего последующего вопроса:

У меня нет ни малейшего представления, почему это работает без всех el: '#app', template: '<App/>', components: { App }

Первое, на что нужно обратить внимание, это то, что свойство экземпляра Vue vm.$el и метод экземпляра Vue vm.$mount() функционально эквивалентны по большей части - каждое позволяет вам указатькорневой элемент DOM, в который будет смонтирован экземпляр Vue.

Основное различие заключается в их применении:

  • Вы используете vm.$el для объявления корневого узла DOM вinstancэлектронное творение.Однако указание значения не обязательно, и если вы этого не сделаете, экземпляр будет создан в несмонтированном состоянии .

  • vm.$mount() позволяет указать корневой узел DOM для неустановленного экземпляра после создания экземпляра.

Как указанов документах:

Если экземпляр Vue не получил опцию el при создании экземпляра, он будет находиться в состоянии «отключен», без связанного с ним элемента DOM.vm. $ mount () можно использовать для ручного запуска монтирования размонтированного экземпляра Vue.

Конечно, если вы используете vm.$mount() вместо vm.$el при создании экземпляра, это в значительной степенивопрос вкуса разработчика (хотя $mount() также принимает различные входные данные, так что здесь есть и другие тонкие различия).Но с точки зрения вашего вопроса практической разницы нет.

Наконец, свойство template Vue и метод render() - это просто две стратегии определения структуры шаблона экземпляра Vue:

  • template - абстракция шаблона верхнего уровня, позволяющая определить шаблон строки ;Например: <div><App/></div>, который Vue анализирует в структуре, создавая при необходимости все дочерние компоненты.

  • render() - это альтернативная низкоуровневая абстракция шаблона, которая на ближеАльтернатива шаблонам для компилятора .Он более гибок для более детальных / программных сценариев использования или для использования с другими языками шаблонов, такими как JSX или raw JS.

Основное очевидное отличие в ваших примерах заключается в том, что template определяет шаблон строки, используя компонент <App/>.Экземпляр Vue должен знать, что это за компонент, перед тем как проанализировать эту строку шаблона, поэтому он должен быть объявлен как компонент.

Принимая во внимание, что render() разрешает передачу компонента App для визуализации напрямую,поэтому не требуется определять template свойство или объявлять какие-либо компоненты.

Я считаю, что первое более явно - что не плохо - и является более декларативным и читаемым при объявлении структурыс несколькими компонентами.С этой целью Vue, по-видимому, рекомендует строки шаблона для большинства случаев использования.Тем не менее, последний подход также может быть аккуратным, и вы часто будете видеть его там, где монтируется один компонент верхнего уровня (например: App).

Другой (неявной) стратегией является шаблон DOM .В отсутствие свойства template или метода render() используется структура HTML, определенная в корневом узле DOM, хотя это обычно не рекомендуется.

Надеюсь, что онЛПС:)

0 голосов
/ 02 июля 2019

Я обнаружил, что проблема может отсутствовать

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

в теле вашего index.html.

0 голосов
/ 19 февраля 2019

Я исправил проблему, обрезав свой main.js, чтобы он содержал только один раздел new Vue, который выглядит следующим образом:

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

У меня нет ни малейшего представления, почему это работает безхотя все эти вещи el: '#app', template: '<App/>', components: { App }, поэтому, если бы это можно было объяснить, я был бы признателен - я не решался добавить ответ, поскольку не знаю , почему это сработало;если кто-то добавит ответ, объясняющий его, я с радостью приму это (или не стесняюсь редактировать мой ответ с объяснением и вырезать этот абзац).

...