Laravel,将JavaScript导入Blade模板的正确方法

47
我正在使用 Laravel 5.6。这个页面 对我无效。

pizza/index.blade.php 的内容如下:

@extends('layouts.app')


@section('content')
    <!-- Styles -->
    <link href="{{ asset('css/pizza.css') }}" rel="stylesheet">
    <!-- Scripts -->
    <script src="{{ asset('js/components/pizza.js')}}"></script>
    <div class="container">
        <div class="row justify-content-center">
            <div class="card">
                <div class="card-header">Pizza</div>
                <div class="card-body">
                    <form action="/pizzas" method="post">
                        @if ($errors->any())
                            <div class="alert alert-danger" role="alert">
                                Please fix the following errors
                            </div>
                        @endif
                        @include('pizza.table')
                    </form>
                </div>
            </div>
        </div>
    </div>
@endsection

pizza/table.blade.php:

<div class="pizza-selection">
    <b>Thanks god its pizza day! Select your pizza of the day!</b>
    <table id="pizzas" class="md-box">
        <tr>
            ...
        </tr>
        @foreach ($pizzas as $pizza)
            ...
        @endforeach
        <tr>
            ...
            <input type="button" class="md-box btn btn-default" 
             id="add_new_pizza" onClick="addPizza()" value="Add Pizza!">
            </td>
        </tr>
    </table>
    ...

当我点击“add_new_pizza”按钮时,出现引用错误,onClick="addPizza()",addPizza()未定义。然而,我尝试在index.blade.php中导入pizza.js文件。
<script src="{{ asset('js/components/pizza.js')}}"></script>

将文本翻译成中文:

打印出asset('js/components/pizza.js')返回http://localhost:8080/js/components/pizza.js,在我看来这是正确的。

public/js/components/pizza.js看起来像下面这样:

import PizzaService from '../services/PizzaService.js';

async function addPizza(){
    // some functionality
}

当我将函数addPizza()放在.blade.php文件内的脚本中时,它也能正常工作。

另外,如果您需要进行代码审查,请在GitHub上找到存储库: https://github.com/andrelandgraf/laravel-docker

编辑:当我将pizza.js复制到<script><script>中时,它可以正常工作,但是我会收到一个SyntaxError:import declarations may only appear at top level of a module。当我像代码示例中所看到的那样通过src导入脚本时,这个SyntaxError就消失了。对我来说,这表明根本没有加载脚本。

编辑2和解决方案:我使用了@kerbholz的解决方案。我在app.blade.php的底部添加了@stack('scripts'),并在index.blade.php的@section('content')内使用@push('stack')来引入pizza.js文件。

我现在进展了一步,但我仍然收到EDIT中指出的SyntaxError。有没有解决方法,还是我只需要删除PizzaService.js的导入并为该文件添加<scipt>-Tag
编辑3:好吧,这个问题与此无关。看起来浏览器尚未支持ES6模块。

1
你的 @section 块之外的任何内容都不会被渲染。 - brombeer
@kerbholz 非常感谢,我不知道这个。我刚开始使用laravel。我编辑了我的问题来解决这个问题,但是我仍然收到相同的错误消息。 - Andre
4个回答

64

在你的 @section 块之外的任何内容都不会被呈现。

你可以编辑你的 layouts/app.blade.php 文件,在你想要样式/ JavaScript 出现的地方添加 @stack('head')(最好放在 HTML 的 <head> 部分)。

在任何一个扩展了 @extends('layouts.app') 的 blade 文件中,你都可以使用

@push('head')
<!-- Styles -->
<link href="{{ asset('css/pizza.css') }}" rel="stylesheet">
<!-- Scripts -->
<script src="{{ asset('js/components/pizza.js')}}"></script>
@endpush

将内容推入该堆栈。

要了解更多信息,请访问https://laravel.com/docs/5.6/blade#stacks


1
通常我会在头部使用 @stack('head'),并在 app.blade.php 的末尾使用 @stack('scripts')。我的做法是创建一个文件 resources/assets/js/_pizza.js,然后在 app.js 中使用 require('./pizza');。(当然,在 app.blade.php 中加载 app.js - brombeer
谢谢你的支持 @kerbholz。现在它对我有用了。push('scripts') 对我起作用了! - Andre
很烦人,我无法直接通过私信或其他方式与您联系。尽管如此,对我来说它是有效的,所以我停止考虑它了,但自从我看到您的评论后一直在想。您如何在laravel中使用require('./ pizza')?据我所知,require来自nodejs,在普通js中不可用,对吗? - Andre
1
@Andre 在普通的JS中没有require,对吧。我想这是来自于webpack/mix - brombeer
1
很高兴为您服务 ;) - brombeer
显示剩余6条评论

15

针对特定页面的自定义脚本:

  • add @yield('footer-scripts') to layouts/app.blade.php

  • create a folder named 'scripts' in views folder

  • inside views/scripts folder create a file 'pizza-script.blade.php' and add the js file contents inside

    <script src="/path/to/pizza.js" />   <!-- it might not work if path isn't clear -->
    
    <script type="text/javascript">
        console.log('executing js here..')
       js file contents....
    
      #if jquery needed add it like, 
    
      $(document).ready(function(){
        ...
      }
    </script>
    
  • in your index.blade.php (or the page where you want the scripts to execute) at the end add the script after @endsection

      @section('footer-scripts')
          @include('scripts.pizza-script')
      @endsection
    
现在刷新页面,你可以在控制台上看到'执行js代码..'

2
尝试将pizza.js移动到index.blade.php底部。
    @section('extra-script')

    {{Html::script('js/components/pizza.js')}}

    @endsection

希望这有所帮助。

谢谢您的回复!我之前看到过Html::,但是在blade.php模板中无法使用。您从哪里获取Html类呢? - Andre
1
你的config/app.php文件应该在providers数组中包含以下代码:'providers' => [ Collective\Html\HtmlServiceProvider::class, ]而aliases应该包含:'aliases' => [ 'Form' => Collective\Html\FormFacade::class, 'HTML' => Collective\Html\HtmlFacade::class, ]如果html无法正常工作,你还可以添加以下内容:<script src="{{ asset('js/components/pizza.js')}}"></script> - Zeeshan Tariq
我发现Laravel Collective是另一个我没有安装的 - Andre
我在你的解决方案中使用了asset(),但仍然收到相同的错误... - Andre
当然可以,但它们并没有真正帮助到您:网络控制台显示:“ReferenceError: addPizza未定义。 onClick localhost:8080/pizzas:1:1” - Andre

1
为了从外部源导入一个库,我写了这个小片段。将其添加到您的layouts/app.blade文件中,在页脚脚本下方的页脚中即可。
    @if(isset($externalJs))
        @foreach ($externalJs as $js)
            <script src="{{$js}}"></script>
        @endforeach
    @endif

然后在你的 Blade 模板中,你可以像这样在文件顶部使用它:

<?php
$externalJs[] = 'path/to/external.js';
?>

可能有其他方法来完成这个任务,但这是一个快速的方法,特别适用于你只有一个文件且不想导入库的情况。


如果您需要多次添加脚本,可能还包括组件中的脚本,我通常会使用 @section('scripts-bottom') <script></script> @append。在这种情况下,您应该使用"@append"而不是"@endsection"。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接