将Stripe JS集成到Laravel 6.0中:[Vue警告]:编译模板时出错:

时间:2019-12-07 08:14:27

标签: javascript laravel stripe-payments laravel-blade

我在checkout.blade.php文件中集成了Stripe.js。它可以工作,但不能没有此错误:

[Vue warn]: Error compiling template:

Templates should only be responsible for mapping the state to the UI. Avoid placing tags with side-effects in your templates, such as <script>, as they will not be parsed

我使错误消失了,但是Stripe Element不会出现在页面上。我还在此文件中集成了其他JS,用于表单验证,可以正常工作,并且不会返回错误。

以下是返回错误的Stripe代码:

<script>
        (function(){
        // Create a Stripe client.
        var stripe = Stripe('pk_test_9dn1vt3i0j0Q5GZdwAXn9iUs00iMziQDyD');

        // Create an instance of Elements.
        var elements = stripe.elements();

        // Custom styling can be passed to options when creating an Element.
        // (Note that this demo uses a wider set of styles than the guide below.)
        var style = {
        base: {
            color: '#32325d',
            fontFamily: '"Helvetica Neue", Helvetica, sans-serif',
            fontSmoothing: 'antialiased',
            fontSize: '16px',
            '::placeholder': {
            color: '#aab7c4'
            }
        },
        invalid: {
            color: 'red',
            iconColor: 'red'
        }
        };

        // Create an instance of the card Element.
        var card = elements.create('card', { style: style, hidePostalCode: true });

        // Add an instance of the card Element into the `card-element` <div>.
        card.mount('#card-element');

        // Handle real-time validation errors from the card Element.
        card.addEventListener('change', function(event) {
        var displayError = document.getElementById('card-errors');
        if (event.error) {
            displayError.textContent = event.error.message;
        } else {
            displayError.textContent = '';
        }
        });

        // Handle form submission.
        var form = document.getElementById('payment-form');
        form.addEventListener('submit', function(event) {
        event.preventDefault();

        stripe.createToken(card).then(function(result) {
            if (result.error) {
            // Inform the user if there was an error.
            var errorElement = document.getElementById('card-errors');
            errorElement.textContent = result.error.message;
            } else {
            // Send the token to your server.
            stripeTokenHandler(result.token);
            }
        });
        });

        // Submit the form with the token ID.
        function stripeTokenHandler(token) {
        // Insert the token ID into the form so it gets submitted to the server
        var form = document.getElementById('payment-form');
        var hiddenInput = document.createElement('input');
        hiddenInput.setAttribute('type', 'hidden');
        hiddenInput.setAttribute('name', 'stripeToken');
        hiddenInput.setAttribute('value', token.id);
        form.appendChild(hiddenInput);

        // Submit the form
        form.submit();
        }
        })();
    </script>

请注意,现在,Stripe代码已嵌套在我的计算机中:

@section('content')

@endsection

由我的父模板'''app.blade.php'''扩展。

如果我将其粘贴到父模板的外面,并用类似这样的包装:

@section('stripe')

@endsection

然后没有错误返回,但是该元素不会出现,因为我的JS不知道将Stripe元素安装在哪里。当然,我在父模板中也有此设置:@yield('stripe')

如何在不出现模板错误的情况下显示我的Stripe Element?

编辑:我使用了Laravel / ui脚手架(Bootstrap版本)。附件如下:

app.js:

require('./bootstrap');

window.Vue = require('vue');

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

ExampleComponent.vue:

<template>
    <div class="container">
        <div class="row justify-content-center">
            <div class="col-md-8">
                <div class="card">
                    <div class="card-header">Example Component</div>

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

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

谢谢

1 个答案:

答案 0 :(得分:1)

正如您在问题中提到的那样,您正在使用laravel/ui中的引导脚手架。根据您用来生成该脚手架的命令,它可以将一些以VueJS为中心的文件或数据安装到常见文件中,这似乎与您有关。尽管您自己对VueJS没做任何事情,但脚手架却为您完成了工作。

在您的 "scripts": { "client": "npm start --prefix client", "server": "node app.js --ignore client", "start": "npm start --prefix client", "dev": "concurrently \"npm run server\" \"npm run client\"", "test": "echo \"Error: no test specified\" && exit 1" }, 文件中,如果您删除或注释掉第3-7行,然后重新运行laravel-mix:


    {
  "name": "client",
  "version": "0.1.0",
  "private": true,
  "proxy": "http://localhost:5000",
  "dependencies": {
    "@fortawesome/fontawesome-svg-core": "^1.2.8",
    "@fortawesome/free-brands-svg-icons": "^5.6.3",
    "@fortawesome/free-solid-svg-icons": "^5.5.0",
    "@fortawesome/react-fontawesome": "^0.1.3",
    "axios": "^0.19.0",
    "react": "^16.10.2",
    "react-dom": "^16.10.2",
    "react-router-dom": "^5.1.2",
    "react-scripts": "3.2.0",
    "react-spring": "^8.0.27"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": "react-app"
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  },
  "devDependencies": {
    "node-sass": "^4.12.0"
  }
}

您将解决您的问题。

如第6行所示,VueJS定位到app.stub中存在的app.js id元素,该元素通常位于require('./bootstrap'); // 3 window.Vue = require('vue'); // 4 // 5 const app = new Vue({ // 6 el: '#app', // 7 }); 下;此视图用作从中扩展其他视图的基础视图。假设app id div封装了大多数page / body元素,则您放在其中的任何内容VueJS都将解释为其基本模板的一部分。这就是为什么您的错误警告不要“将脚本标签放入模板中”的原因。

如上所述,对resources/views/layouts/app.blade.php文件的上述更改当然可以解决问题,因为它将VueJS排除在外。也就是说,但是,如果您根本不打算使用VueJS,也可以将其从app文件中删除,然后运行npm prune删除未使用的软件包(如{中未指定的任何软件包{1}}(并且不需要作为其他软件包的依赖项)来从您的网站中完全删除该库。