Laravel Mix Vue,使用Vue Router时,延迟加载组件作为未知的自定义元素返回错误

时间:2018-08-29 16:55:48

标签: vue.js lazy-loading vue-router laravel-mix

我已经重新安装了Laravel Mix,我正在尝试在项目中设置延迟加载组件。我已经使用babel插件'syntax-dynamic-import'进行了正确的设置,因此app.js中的import语句可以按预期工作。当我尝试将延迟加载的组件与vue-router一起使用时,会发生此问题。

我的app.js文件如下:

require('./bootstrap');

import Vue from 'vue';
import VueRouter from 'vue-router';

Vue.use(VueRouter);

const EC = () => import(/* webpackChunkName: "example-component" */ './components/ExampleComponent.vue');

const router = new VueRouter({
    mode: 'history',
    routes: [
        { path: '/', component: EC }
    ]
});

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

和我的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" content="{{ csrf_token() }}">

    <title>Laravel</title>

    <link href="{{ asset('css/app.css') }}" rel="stylesheet">

    <base href="/" />
</head>
<body>
<div id="app">
    <h1>Base title</h1>
    <example-component></example-component>
</div>

<script src="{{ asset('js/app.js') }}"></script>
</body>
</html>

所以我只是试图着陆并显示示例组件。该示例组件包含在welcome.blade.php文件中。

我在控制台中收到此错误:

[Vue warn]: Unknown custom element: <example-component> - did you register the component correctly? For recursive components, make sure to provide the "name" option.

(found in <Root>)

我想我缺少一些简单的东西,任何建议都值得赞赏。

3 个答案:

答案 0 :(得分:0)

首先,我认为您正在将路线概念与核心组件vue概念相结合...

尝试直接在vue应用程序中加载组件...

const app = new Vue({
    router,
    el: '#app',
    components: {
        'example-component': () => import('./components/ExampleComponent.vue')
    }
});

使用<component>

完成组件加载
<component v-bind:is="currentTabComponent"></component>

检查文档,以获取有关动态组件的更多信息:https://vuejs.org/v2/guide/components-dynamic-async.html

答案 1 :(得分:0)

@Erubiel的回答确实有效,但它仍然不是我想要的设置。当我尝试使用vue-router时,我需要通过删除对组件的显式调用并在welcome.blade.php文件中添加标签来更新视图。现在这意味着我的路线已注入该空间。更新的区域是:

...
<body>
<div id="app">
    <router-view></router-view>
</div>

<script src="{{ asset('js/app.js') }}"></script>
</body>
...

答案 2 :(得分:0)

问题出在Vue中的scss splitting中,并且同时使用了mix.scss()。当Laravel和Laravel都创建了其中包含清单js文件内容的css文件时,就会进行混合。这绝对是一个错误。社区中提到了来自Webpack的错误,并将在webpack 5中解决。但是,如果您仅在Vue中使用代码拆分,并且将默认的app.scss文件导入到这样的主要Vue组件中(不在范围内),因此每个其他组件将正确获得样式

// resources/js/components/app.vue
<template>
 <!-- Main Vue Component  -->
</template>

<script>
// Main Script
</script>

<style lang="scss">
  @import '~@/sass/app.scss';
</style>

,并且webpack.mix.js文件将没有mix.scss函数,只能运行一个app.js文件。这是我的文件。

// webpack.mix.js
const mix = require('laravel-mix')
mix.babelConfig({
  plugins: ['@babel/plugin-syntax-dynamic-import'] // important to install -D
})

mix.config.webpackConfig.output = {
  chunkFilename: 'js/[name].bundle.js',
  publicPath: '/'
}

mix
  .js('resources/js/app.js', 'public/js')
  .extract(['vue'])
  .webpackConfig({
    resolve: {
      alias: {
        '@': path.resolve('resources/') // just to use relative path properly
      }
    }
  })

希望这可以解决每个人的问题