Что касается исходной проблемы:
Как я уверен, вы знаете из обсуждения комментариев, ошибки [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, хотя это обычно не рекомендуется.
Надеюсь, что онЛПС:)