• laravel中使用vue热加载时 Cannot read property 'call' of undefined BUG解决方案


    一、文件初始化

    [routes/web.php]

    Route::group(['namespace' => 'Home'], function () {
        Route::get( '/', 'IndexController@index');
    });
    

    [app/Http/Controllers/Home/IndexController.php]

    namespace AppHttpControllersHome;
     
    class IndexController
    {
        public function index () {
            return view('home.index');
        }
    }
    

      

    [resources/views/layouts/app.blade.php]

    <!doctype html>
    <html lang="{{ app()->getLocale() }}">
    <head>
    <meta charset="UTF-8">
    <meta name="viewport"
    content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <meta name="csrf-token" content="{{ csrf_token() }}">
    <title> @yield('title', 'Laravel') </title>
    </head>
    <body>
    <div id="app">
    @yield('content')
    </div>
    <script src="{{ mix('/js/app.js') }}"></script>
    </body>
    </html>

      

    [resources/views/home/index.blade.php]

    @extends('layouts.app')

    @section('content')
    <example></example>
    @endsection

      

    [resources/assets/js/app.js]

    import Vue from 'vue'
     
    import Example from './components/example.vue'
     
    Vue.component( 'example', Example)
     
    new Vue({
        el: '#app'
    })
    

      

    [resources/assets/js/components/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>
    

      

    [webpack.mix.js]

    let mix = require('laravel-mix');
     
    mix
        .js('resources/assets/js/app.js', 'public/js')
        .sass('resources/assets/sass/app.scss', 'public/css')
    

      

    以上这个文件状况然后再执行以下命令:

    php artisan serve
    npm run hot
    

      

    然后我们打开页面 http://localhost:8000/

    这个时候,页面是正常的vue和webapck-dev-server以及热加载都是正常的。

    二、代码分离(按官方文档分离后出现BUG)

    但是,考虑到这样开发之后,所有的vue代码全部打包到了 [public/js/app.js] 这一个文件中,所以开始考虑使用webpack的代码分离功能。

    根据 laravel-mix 的官方文档

    https://github.com/JeffreyWay/laravel-mix/blob/master/docs/extract.md#library-code-splitting

    然后我们修改文件:

    [webpack.mix.js]

    let mix = require('laravel-mix');
     
    mix
        .js('resources/assets/js/app.js', 'public/js')
        .extract(['vue'])
        .sass('resources/assets/sass/app.scss', 'public/css')
    

      

    这样修改之后,我们将 vue 作为供应库(第三方库) 打包在 [js/vendor.js] ,并同时生成 [js/manifest.js] 

    然后我们再将 manifest.js , vendor.js 引入到模板:

    [resources/views/layouts/app.blade.php]

    <!doctype html>
    <html lang="{{ app()->getLocale() }}">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport"
              content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <meta name="csrf-token" content="{{ csrf_token() }}">
        <title> @yield('title', 'Laravel') </title>
    </head>
    <body>
        <div id="app">
            @yield('content')
        </div>
        <script src="{{ mix('/js/manifest.js') }}"></script>
        <script src="{{ mix('/js/vendor.js') }}"></script>
        <script src="{{ mix('/js/app.js') }}"></script>
    </body>
    </html>
    

      

    再重新执行以下命令:

    php artisan serve
    npm run hot
    

      

    然后我们打开页面 http://localhost:8000/

    此时我们发现控制台会出现一个这样的错误:Cannot read property 'call' of undefined

    143814_sTXx_2647760.png

    这个错误的来自一个webpack引入一个webpack-dev-server模块导致了,具体原因不明确:

    143928_rjkX_2647760.png

    三、解决方案

    修改文件:

    [webpack.mix.js]

    let mix = require('laravel-mix');
     
    mix
        .js('resources/assets/js/app.js', 'public/js')
        .extract(['vue'], 'public/js/vendor.js')
        .sass('resources/assets/sass/app.scss', 'public/css')
    

      

    然后重新运行 

    npm run hot
    

      

    这个时候就没问题。

    关于 mix.extract() 这个方法 我们查看源码是这样的

     
        /**
         * Register vendor libs that should be extracted.
         * This helps drastically with long-term caching.
         *
         * @param {Array}  libs
         * @param {string} output
         */
        extract(libs, output) {
            Config.extractions.push({ libs, output });
     
            return this;
        };
    

      

    也就是说,我们其实可以手动指定打包之后的输出目录。

  • 相关阅读:
    rebar
    namenode ha
    jmx
    doclint in jdk8
    maven source
    avd
    ccw-ide
    ST3使用
    Web worker
    离线web-ApplicationCache
  • 原文地址:https://www.cnblogs.com/mmykdbc/p/15266854.html
Copyright © 2020-2023  润新知