【问题标题】:Vue 2.0 - Failed to mount component: template or render function not defined despite defined render functionVue 2.0 - 无法安装组件:尽管定义了渲染函数,但未定义模板或渲染函数
【发布时间】:2016-11-18 19:16:14
【问题描述】:

使用 Vue 2.0 处理 SPA。我通过 Laravel Elixir、laravel-elixir-webpack-official 和 laravel-elixir-vue-2 将所有模板与来自 .vue 文件的 Webpack 捆绑在一起。我已经审查了几乎所有关于此的现有问题,其中大部分是指需要独立构建或在您的 gulpfile 中调用 elixir 函数两次,据我了解,这两个都不适用。

完整的控制台错误:

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

ma​​in.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'
      });
});

【问题讨论】:

    标签: vue.js laravel-elixir


    【解决方案1】:

    由于您使用的是 ES2015,您可以这样做:

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

    render 是一个对象属性,它是一个函数。您拥有的是有效的 Javascript 语法,但这不是 VueJs 设置您的 vue 实例所需的签名。

    【讨论】:

      【解决方案2】:

      这个错误通常来自于拉入不包含 vue 模板解析器的默认 vue.common.js。如果您将 Vue 导入更改为:

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

      这样能解决吗?

      如果是这样,则说明您的 Elixir 设置存在问题。如果设置正确,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' 是我建议这样做的主要原因,因为它不支持 Vue 或 Vuex 的 v2,它们可能会发生重大变化。

      附带说明,您的 gulpfile 中不需要 require('laravel-elixir-webpack-official')

      为了解决问题,我可能会建议您单独全新安装 laravel,以便您可以比较您的 package.json、main.js 和 gulpfile。


      修复 webpack 中的图片引用

      根据您的最新评论,您编译的错误是由于您错误地引用了图像位置引起的。

      如果您使用的是最新版本的 laravel,那么您有 2 个默认选项来存储图像。要么将它们放在resources/assets 中,要么放在images 目录中。或者将它们再次放在storage/app/public 中的images 目录中。

      第一个位置:resources/assets 然后由 webpack 处理,并在编译时将这些图像缩小、散列并复制到: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">
      

      【讨论】:

      • 不幸的是,使用import Vue from 'vue/dist/vue.js' 并不能解决问题。那是我尝试的第一件事。
      • 我添加了我的 gulpfile 以防出现问题
      • 在您发布 gulp 文件后更新了答案
      • nextvuex-router-sync 分支确实支持 Vue2。话虽如此,我正在从 gulpfile 中删除 laravel-elixir-webpack-official 并精简到默认 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'
      • 更新了查看图像参考问题的答案 - 这确实假设您已根据您的最后评论删除了 mix.copy 和 mix.tinypng,因为这些可能会弄乱事情并查看您的 gulpfile 不是t 需要作为默认的 laravel webpack 应该为您处理所有这些。
      猜你喜欢
      • 2017-02-25
      • 2020-07-28
      • 2019-12-05
      • 2018-07-05
      • 1970-01-01
      • 2019-11-11
      • 2020-06-14
      • 2018-03-01
      • 2018-12-20
      相关资源
      最近更新 更多