Vue 2.0 - Не удалось смонтировать компонент: шаблон или функция рендеринга не определены, несмотря на определенную функцию рендеринга

Работа над SPA с использованием Vue 2.0. Я связываю все свои шаблоны с Webpack из файлов .vue через Laravel Elixir, laravel-elixir-webpack-official и laravel-elixir-vue-2. Я просмотрел почти все существующие вопросы по этому поводу, большинство из которых относятся к необходимости автономной сборки или двойному вызову функции elixir в вашем gulpfile, ни один из которых не применим, насколько я понимаю.

Полная ошибка консоли:

[Vue warn]: Failed to mount component: template or render function not defined. (found in anonymous component at E:\dev\project\resources\assets\js\App.vue)

main.js:

import Vue from 'vue';
var VueResource = require('vue-resource');
Vue.use(VueResource);
import VueRouter from 'vue-router'
Vue.use(VueRouter)

import { sync } from 'vuex-router-sync'
import store from './vuex/store';

import Home from './views/home.vue';
import Toast from './views/toast.vue';

const routes = [
    {
        path: '/',
        name: 'home',
        component: Home
    },
    {
        path: '/toast',
        name: 'toast',
        component: Toast
    }
]
const router = new VueRouter({
    routes: routes
});

sync(store, router) // done.

import App from './App.vue'

new Vue({
  name: 'app',
  el: '#app',
  store,
  router,
  render(h) {
    return h(App)
  }
});

App.vue:

<script>
    // App.js
    import Header from './components/Header.vue'
    import Loading from './components/Loading.vue';
    import Messenger from './components/Messenger.vue';

    export default {
        components: {
            Header, Loading, Messenger
        }
    }
</script>

<template>
    <div>
      <header></header>
      <router-view></router-view>
      <loading></loading>
      <messenger></messenger>
    </div>
</template>

И сайт загружается через блейд-шаблон, очень просто:

<body>
   <div id="app">

   </div>
   <script type="text/javascript" src="https://js.stripe.com/v2/"></script>
   <script src="/js/main.js"></script>
</body>

Учитывая все это, я почти уверен, что мне не нужна отдельная сборка. Может ли кто-нибудь помочь мне понять, что здесь не так?

Дополнительная информация

Если я открою Vue devtools, я увижу корневой компонент приложения. Под ним находится один анонимный компонент, на котором стоит $route. Вот и все.

Gulpfile

var elixir = require('laravel-elixir');

require('laravel-elixir-vue-2');
require('elixir-tinypng');
require('laravel-elixir-webpack-official');
var env = require('./env.json');

elixir(function(mix) {
  // Image optimization
    if(env.tinyPngApiKey) {
      mix.tinypng({
        key:env.tinyPngApiKey,
        sigFile:'.tinypng-sigs',
        log:true,
        summarize:true
      });

      // Copy all non compressible images to build
      mix.copy('assets/img/*.!(png|jpg)', 'resources/img');
    } else {
      mix.copy('assets/img/*', 'resources/img');
    }
    mix.copy('node_modules/font-awesome/fonts', 'public/fonts')
      .sass('app.scss')
      .webpack('main.js')
      .browserSync({
         proxy: 'project.dev'
      });
});

person Ethan C    schedule 18.11.2016    source источник


Ответы (2)


Поскольку вы используете ES2015, вы можете сделать это:

new Vue({ // eslint-disable-line no-new
  name: 'app',
  el: '#app',
  render: (h) => h(App),
  router
});

render — это свойство объекта, которое является функцией. У вас есть допустимый синтаксис Javascript, но это не подпись, которая требуется VueJs для настройки вашего экземпляра vue.

person Daniel Verem    schedule 19.11.2016

эта ошибка обычно возникает из-за загрузки файла vue.common.js по умолчанию, который не включает анализатор шаблонов vue. Если вы измените свой импорт Vue на:

import Vue from 'vue/dist/vue.js'

Это исправит?

Если это так, то это проблема с настройкой Эликсира. laravel-elixir-vue-2 должен использовать псевдоним vue для этой версии, если он установлен правильно. Вы не разместили свой файл gulp, но он должен выглядеть примерно так:

const elixir = require('laravel-elixir');

require('laravel-elixir-vue-2');

elixir(mix => {

    mix.sass('app.scss')
       .webpack('main.js')

})

Снова взглянув на ваш файл gulp и main.js, я понял, что у вас есть расхождения между файлами, которые вам нужны. Я предполагаю, что проблема именно в этом — у вас, вероятно, установлена ​​неправильная версия Vue или один из его пакетов.

«vuex-router-sync» — это основная причина, по которой я предлагаю это, поскольку это не поддерживает v2 Vue или Vuex, которые, вероятно, будут иметь критические изменения.

Кстати, вам не нужно require('laravel-elixir-webpack-official') в вашем gulpfile.

Чтобы исправить ситуацию, я, вероятно, порекомендовал бы отдельную новую установку laravel, чтобы вы могли сравнить свой package.json, main.js и gulpfile.


Исправление ссылок на изображения в веб-пакете

После вашего последнего комментария ошибки, которые вы столкнулись с компиляцией, вызваны тем, что вы неправильно указали расположение своих изображений.

Если вы используете последнюю сборку laravel, у вас есть 2 варианта хранения изображений по умолчанию. Либо поместите их в resources/assets, возможно, в каталог images. Или поместите их снова в storage/app/public в каталоге images.

Первое местоположение: resources/assets затем обрабатывается веб-пакетом, и при компиляции эти изображения будут минимизированы, хешированы и скопированы в: public/img. Чтобы сослаться на любое из этих изображений в вашем приложении Vue, вы просто определяете путь к ним из файла, в котором работаете, т.е.

# resources/assets/js/components/example.vue
<img src="../../images/logo.png">

указывает на resources/assets/images/logo.png

Однако, если вы хотите обслуживать статические изображения (без хеширования, минимизации и т. д.), просто поместите их в storage/app/public/images и сошлитесь на них, например:

<img src="/images/logo.png">
person GuyC    schedule 19.11.2016
comment
К сожалению, использование import Vue from 'vue/dist/vue.js' не помогает. Это было первое, что я попробовал. - person Ethan C; 20.11.2016
comment
Добавил gulpfile на всякий случай что-то торчит - person Ethan C; 20.11.2016
comment
Обновлен ответ после публикации файла gulp. - person GuyC; 20.11.2016
comment
next ветвь vuex-router-sync поддерживает Vue2. При этом я удаляю laravel-elixir-webpack-official из gulpfile и урезаю до того, что находится в установке laravel по умолчанию, и того, что я использую во внешнем интерфейсе. Когда я это делаю, он пытается скомпилировать все в моих .vue файлах как Javascript и зависает каждый раз, когда я ссылаюсь на изображение в css: Module not found: Error: Can't resolve '../img/beer.png' in 'E:\dev\project\resources\assets\js\components' resolve '../img/beer.png' in 'E:\dev\project\resources\assets\js\components' - person Ethan C; 23.11.2016
comment
обновленный ответ, чтобы посмотреть на проблемы со ссылками на изображения - это предполагает, что вы удалили mix.copy и mix.tinypng в соответствии с вашим последним комментарием, так как они, вероятно, испортят вещи, и просмотр вашего gulpfile не требуется, поскольку веб-пакет laravel по умолчанию должен справиться с этим все для вас. - person GuyC; 23.11.2016
comment
Ладно, это дало мне повод продолжить. Изображения, на которые он жалуется, находятся в моих файлах sass/scss. В моих тегах стиля .vue я импортирую свой основной файл app.scss, поэтому у меня есть доступ к переменным и миксинам, и там есть несколько ссылок на изображения, которые ему не нравятся. Как с этим справиться? - person Ethan C; 23.11.2016
comment
Скорее всего, ваша проблема заключается в том, что при импорте SASS ссылки на изображения должны относиться к файлу vue, а не к файлу SASS. Очевидно, что это не идеально, поэтому вы можете захотеть установить псевдонимы для каталогов в вашем объекте разрешения веб-пакетов, т.е. resolve: { ... alias: { 'images': path.resolve(__dirname, '../resources/assets/images') просто добавьте файл webpack.config.js в корень вашего проекта, чтобы установить новые параметры. - person GuyC; 24.11.2016