无法在新的laravel 5.5项目上安装组件 [英] Failed to mount component on new laravel 5.5 project

查看:59
本文介绍了无法在新的laravel 5.5项目上安装组件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在使用vue js时,

我和同事在新老laravel项目中都遇到了问题,因为我们每次在浏览器控制台中都会遇到以下错误

me and a colleague have been having problems in new and old laravel projects when it comes to using vue js because we get the following error every time in the browser console

>`[Vue warn]: Failed to mount component: template or render function not defined.
found in
---> <Example>
       <Root>
warn @ app.js:32173
mountComponent @ app.js:34241
Vue$3.$mount @ app.js:39678
Vue$3.$mount @ app.js:41868
init @ app.js:35260
createComponent @ app.js:36909
createElm @ app.js:36852
createChildren @ app.js:36980
createElm @ app.js:36885
patch @ app.js:37394
Vue._update @ app.js:34147
updateComponent @ app.js:34271
get @ app.js:34614
Watcher @ app.js:34603
mountComponent @ app.js:34275
Vue$3.$mount @ app.js:39678
Vue$3.$mount @ app.js:41868
Vue._init @ app.js:36000
Vue$3 @ app.js:36085
(anonymous) @ app.js:802
__webpack_require__ @ app.js:20
(anonymous) @ app.js:775
__webpack_require__ @ app.js:20
(anonymous) @ app.js:63
(anonymous) @ app.js:66`

即使在使用默认Example.vue的新laravel项目中,也会发生这种情况

This happens even in new laravel projects using the default Example.vue

我当前的代码如下

Example.vue

Example.vue

<template>
    <div class="container">
        <div class="row">
            <div class="col-md-8 col-md-offset-2">
                <div class="panel panel-default">
                    <div class="panel-heading">Example Component</div>

                    <div class="panel-body">
                        I'm an example component!
                    </div>
                </div>
            </div>
        </div>
    </div>
</template>

<script>
    export default {
        mounted() {
            console.log('Component mounted.')
        }
    }
</script>

assets/js/app.js

assets/js/app.js

/**
 * First we will load all of this project's JavaScript dependencies which
 * includes Vue and other libraries. It is a great starting point when
 * building robust, powerful web applications using Vue and Laravel.
 */

require('./bootstrap');

window.Vue = require('vue');

/**
 * Next, we will create a fresh Vue application instance and attach it to
 * the page. Then, you may begin adding components to this application
 * or customize the JavaScript scaffolding to fit your unique needs.
 */

Vue.component('example', require('./components/Example.vue'));

const app = new Vue({
    el: '#app'
});

assets/js/bootstrap.js

assets/js/bootstrap.js

window._ = require('lodash');

/**
 * We'll load jQuery and the Bootstrap jQuery plugin which provides support
 * for JavaScript based Bootstrap features such as modals and tabs. This
 * code may be modified to fit the specific needs of your application.
 */

try {
    window.$ = window.jQuery = require('jquery');

    require('bootstrap-sass');
} catch (e) {}

/**
 * We'll load the axios HTTP library which allows us to easily issue requests
 * to our Laravel back-end. This library automatically handles sending the
 * CSRF token as a header based on the value of the "XSRF" token cookie.
 */

window.axios = require('axios');

window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';

/**
 * Next we will register the CSRF Token as a common header with Axios so that
 * all outgoing HTTP requests automatically have it attached. This is just
 * a simple convenience so we don't have to attach every token manually.
 */

let token = document.head.querySelector('meta[name="csrf-token"]');

if (token) {
    window.axios.defaults.headers.common['X-CSRF-TOKEN'] = token.content;
} else {
    console.error('CSRF token not found: https://laravel.com/docs/csrf#csrf-x-csrf-token');
}

/**
 * Echo exposes an expressive API for subscribing to channels and listening
 * for events that are broadcast by Laravel. Echo and event broadcasting
 * allows your team to easily build robust real-time web applications.
 */

// import Echo from 'laravel-echo'

// window.Pusher = require('pusher-js');

// window.Echo = new Echo({
//     broadcaster: 'pusher',
//     key: 'your-pusher-key'
// });

welcome.blade.php

welcome.blade.php

<!doctype html>
<html lang="{{ app()->getLocale() }}">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <meta name="csrf-token" value="{{csrf_token()}}">
        <title>Laravel</title>

        <!-- Fonts -->
        <link href="https://fonts.googleapis.com/css?family=Raleway:100,600" rel="stylesheet" type="text/css">
        <link rel="stylesheet" type="text/css" href="/css/app.css">
        <!-- Styles -->

    </head>
    <body>

        <div id="app">
            <example></example>
        </div>
        <script type="text/javascript" src="/js/app.js"></script>
    </body>
</html>

webpack.mix.js

webpack.mix.js

let mix = require('laravel-mix');

/*
 |--------------------------------------------------------------------------
 | Mix Asset Management
 |--------------------------------------------------------------------------
 |
 | Mix provides a clean, fluent API for defining some Webpack build steps
 | for your Laravel application. By default, we are compiling the Sass
 | file for the application as well as bundling up all the JS files.
 |
 */

mix.js('resources/assets/js/app.js', 'public/js')
   .sass('resources/assets/sass/app.scss', 'public/css');

package.json

package.json

{
  "private": true,
  "scripts": {
    "dev": "npm run development",
    "development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
    "watch": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --watch --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
    "watch-poll": "npm run watch -- --watch-poll",
    "hot": "cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --config=node_modules/laravel-mix/setup/webpack.config.js",
    "prod": "npm run production",
    "production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js"
  },
  "devDependencies": {
    "axios": "^0.16.2",
    "bootstrap-sass": "^3.3.7",
    "cross-env": "^5.0.1",
    "jquery": "^3.1.1",
    "laravel-mix": "^1.0",
    "lodash": "^4.17.4",
    "vue": "^2.1.10"
  },
  "dependencies": {
    "cross-env": "^5.0.5",
    "vee-validate": "^2.0.0-rc.17"
  }
}

推荐答案

如果您未进行任何更改且已正确捆绑并安装了JavaScript,则问题可能出在默认的Laravel实现上.

If you haven't changed anything and and have correctly bundled and installed JavaScript then the issue may lie with the default Laravel implementation.

您收到的错误消息意味着您很可能将仅运行时内部版本(不需要模板编译器的情况下)导入需要模板编译器的应用程序中.

The error message you are receiving means that you are likely importing the runtime only build (vue without the template compiler) in to an app that needs the template compiler.

为了更好地理解这一点,Vue将所有内容编译为渲染函数(本质上是网页的纯JavaScript表示形式).使用单个文件组件时,您最终只能得到一个基本组件您将其安装到您的Vue实例,该实例将提供您的所有视图,因此,我们将获得以下内容:

To better understand this, Vue compiles everything into render functions (essentially a pure JavaScript representation of your webpage). When using single file components you end up with one base component that you mount to your Vue instance, which serves up your all your views, so, we would get something like this:

components/App.vue

<template>
  <div>
    I'm a base component
    <!-- vue-router will mount components here -->
    <router-view></router-view>
  </div>
</template>

app.js

import App from './components/App.vue' 

// "h" is just a standard taken from JSX
new Vue({
  render: h => h(App)
}).$mount("#app");

app.blade.php

<html>
  <head>
    <!-- head stuff -->
  </head>
  <body>
    <div id="app"></div>
    <script src="app.js"></script>
  </body>
</html>

这里重要的是,app.blade.php仅充当整个应用程序的安装点,而App.vue充当基础组件,而转弯又可以服务于其他所有视图(通常通过 vue-路由器).为了使它起作用,我们需要通过webpack将资产编译为app.js,这将为我们创建所有渲染函数,因此我们不需要编译器,因为所有内容都已编译.剩下要做的就是在routes/web.php中创建一条路由来提供索引刀片文件.这实际上是在设置SPA.

The important thing here is that app.blade.php only acts as a mounting point for your entire app and App.vue serves as the base component, which is turns serves every other view (this would usually be done via vue-router). To get that to work we need to compile our assets into app.js via webpack, which creates all our render functions for us, so we don't need the compiler because everything has already been compiled. All that's left to do is create a route in routes/web.php to serve up the index blade file. That's essentially setting up an SPA.

Laravel鼓励您做的是直接在标记中添加Vue组件并在全局范围内注册组件,因此您可以这样做:

What Laravel encourages you do, is add Vue components directly in your markup and register components globally, so you would do:

app.js

Vue.component('my-component', require('./components/My-component.vue'));

const app = new Vue({
    el: '#app'
});

index.blade.php

<html>
  <head>
    <!-- head stuff -->
  </head>
  <body>
    <div id="app">
      <my-component></my-component>
    </div>
    <script src="app.js"></script>
  </body>
</html>

因为我们已将组件添加到标记中,所以我们需要模板编译器在运行时将app div标签之间的位编译为渲染函数.因此,我们需要导入vue +编译器,这是Laravel Mix 应该通过为Vue的runtime + compiler版本起别名来为您完成的(您可以找到有关如何执行此操作的详细信息

Because we've added our component to the markup we need the template compiler to compile the bit between our app div tags into a render function at runtime. So, we need to import vue + compiler, which is what Laravel Mix should do for you by aliasing the runtime + compiler version of Vue (you can find details of how to do that in the docs).

说实话,我不是Laravel Mix的粉丝,因为它抽象出了作为开发人员您需要了解的关键实现细节,例如"Laravel Mix是否正确地别名了Vue + compiler构建"?,在您的情况下看起来并非如此.

To be honest, I'm not a fan of Laravel Mix because it abstracts away crucial implementation details that as a developer you need to know, such as, "is Laravel Mix correctly aliasing the Vue + compiler build"?, in your case it looks like it isn't.

最后,直接设置自己的webpack配置通常更容易,这样您就可以完全控制配置了,可以使用Vue的

In the end it's usually easier to just setup your own webpack config directly so you have total control over your config, you can use Vue's webpack simple config as a base.

一旦您正确设置了webpack,就需要将别名添加到webpack配置中,并且您就可以构建runtime + compiler:

Once you've correctly setup webpack, you just then need to add the alias to webpack config and you have your runtime + compiler build in:

 resolve: {
    alias: {
      'vue$': 'vue/dist/vue.esm.js'
    }
  }

我意识到我并没有真正关心您的具体问题.我发现很难相信Webpack Mix没有正确地别名vue + compiler构建,但这就是该消息的含义.希望如此,它可以为您提供足够的信息以查找问题所在.

I realise that I haven't really given a soultion to your specific problem. I find it hard to believe that Webpack Mix isn't correctly aliasing the vue + compiler build, but that is what that message implies. Hopefully though, this gives you enough information to find where the problem lies.

这篇关于无法在新的laravel 5.5项目上安装组件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆