Importing stripe to a Vue.js component - vue.js

https://alligator.io/vuejs/stripe-elements-vue-integration/
On this website, it says we need to import the file with the script tag in the index.html file, which I did, but I noticed I get a js error.
It's only when I imported directly the script inside the component that the error "'Stripe' is not defined" disappeared.
<template>
<div>
</div>
</template>
<script src="https://js.stripe.com/v3/"></script>
<script>
export default {
name: 'component',
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
</style>
I don't want to import it directly inside my component, because it's not clean, what can I do?
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<script src="https://js.stripe.com/v3/"></script>
<title>vue-app</title>
</head>
<body>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>

Late to the party, but here is a solution that works for me
Your index.html file looks fine:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<script src="https://js.stripe.com/v3/"></script>
<title>vue-app</title>
</head>
<body>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
Then in the component where you want to use it, you can access stripe with the window object, and set the publishable key. This can be done locally in a method, or globally for the component, like this:
<script>
const stripe = window.Stripe(process.env.VUE_APP_STRIPE_PK)
export default {
data() {
return {
// ...
}
},
methods: {
async confirmPayment() {
const paymentResult = await stripe.confirmCardPayment(this.clientSecret, {
receipt_email: 'email#example.com',
})
console.log('paymentResult:', paymentResult)
},
},
}
</script>

I think you should move the script tag of Stripe before the rest of your JavaScript code. The code is probably trying to access the Stripe object before it's been loaded.

Related

Vue component does not render

I am trying to get a vue component to work from a separate file called AppButton.js. This simple learning component should render a button with some css and disables the click when one hovers over the button. Instead, this code just displays text. I cannot figure out what is missing in my code and I would appreciate if someone can take a look.
Here is the content from AppButton.js:
export default {
template: '<button class="bg-gray-200 hover:bg-gray-400 border rounded px-5 py-2 disabled:cursor-not-allowed" v-bind:disabled="processing"><slot /></button>',
data() {
return {
processing: true
}
}
}
The AppButton.js is in the same directory as my index.html. Here is the content of the index.html.
<!DOCTYPE html>
<html lang="en" class="h-full">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://unpkg.com/vue#3"></script>
<script src="https://cdn.tailwindcss.com"></script>
</head>
<body class="h-full grid place-items-center">
<div id="app">
<app-button>Scura</app-button>
</div>
<script type="module">
import AppButton from "AppButton.js"
let app = {
components: {
'app-button': AppButton
}
};
Vue.createApp(app).mount('#app');
</script>
</body>
</html>
I tried loading vue.js devtools extension in my Chrome to debug this problem further but for some reason the vue.js devtools extension does not show in my devtools
This is the error I am getting in Chrome Console: Access to script at
'file:///C:/Users/scura/Documents/LearnHtmlCss/js/components/AppButton.js' from origin 'null' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, chrome-untrusted, https.
index.html:18 GET file:///C:/Users/scura/Documents/LearnHtmlCss/js/components/AppButton.js net::ERR_FAILED

How could I mount the app in to index.html

I am pretty new to Vue.js.
I am trying to build a project without cli.
I've tried to add the CDN into the index.html.
and create a app.js file , add it to index.html and it works well.
Then I watch some youtube and tutorial, the idea of component kicks in and I am trying to add the Single-File Components into the project.
But I do not know how to structure the files so that it could work with the components.
Here are what I've got so far , could someone please tell me what's wrong here?
Any suggestions would be appreciated.
Many Thanks.
Oren
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>new Vue project</title>
<link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap/dist/css/bootstrap.min.css" />
<link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap-vue#latest/dist/bootstrap-vue.min.css" />
<link rel="stylesheet" href="style.css">
</head>
<body>
<div id="app"></div>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script src="main.js"></script>
main.js
import { createApp } from "vue";
import App from "./App.vue";
createApp(App).mount("#app");
App.vue
<template>
<div class="container">
<Header />
</div>
</template>
<script>
import Header from './src/components/Header'
export default {
name:'App',
components:{
Header,
},
data(){
return{
test:'oren testing'
}
}
}
</script>
SFCs require a build step and is recomended
When using standard Vue without a build step and mounting to in-DOM templates, it is much less optimal because:
We have to ship the Vue template compiler to the browser (13kb extra size)
The compiler will have to retrieve the template string from already instantiated DOM
The compiler then compiles the string into a JavaScript render function
Vue then replaces existing DOM templates with new DOM generated from the render function.
If you still don't want a build step, take a look at petite-vue

Error resolving module specifier “vue”. Relative module specifiers must start with “./”, “../” or “/”

I'm trying to get a basic VueJS application working using the code
<!DOCTYPE html>
<html>
<head>
<script src="https://unpkg.com/vue#3"></script>
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
</head>
<body>
<div id="app"></div>
<script type="module">
import { createApp } from 'vue'
import MyComponent from './my-component.js'
createApp(MyComponent).mount('#app')
</script>
</body>
</html>
But all I see is the error of 'Error resolving module specifier “vue”. Relative module specifiers must start with “./”, “../” or “/”.' when I browse to localhost:3000 on Firefox. I've been at this for hours but I can't figure out why it doesn't work when I've copied it from the VueJS page 'getting started'. I've used the commands 'npm run dev', 'npx serve' and 'npm run build' but they all return the same error in the web developer tools' console.
Any help or guidance on this would be appreciated.
It seems that you are using the global build of Vue where all APIs are exposed under the global Vue variable (line 4 in your example).
Solution 1
Remove the import line for vue and prepend createApp with "Vue.":
//REMOVED: import { createApp } from 'vue'
import MyComponent from './my-component.js'
Vue.createApp(MyComponent).mount('#app') //NOTE that "Vue." has been added
Solution 2
Another solution would be to add an importmap block. That way, you can refer to vue as specified in the importmap and the corresponding url is resolved from there. Unfortunately, this is (at the moment) only supported by Chromium-based browsers. Luckily, a shim is available to allow use of importmap on non-Chromium browsers.
See below for an example, where the shim is injected above the importmap-block. Note that the script-line for loading vue has been removed from the header-block.
<!DOCTYPE html>
<html>
<head>
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
</head>
<body>
<script async src="https://ga.jspm.io/npm:es-module-shims#1.4.6/dist/es-module-shims.js"></script>
<script type="importmap">
{ "imports": { "vue": "https://unpkg.com/vue#3/dist/vue.esm-browser.js" } }
</script>
<div id="app">{{ message }}</div>
<script type="module">
import { createApp } from 'vue' createApp({ data() { return { message: 'Hello Vue!' } } }).mount('#app')
</script>
</body>
</html>

import vanilla javascript in Vue.js

i am working on a project using Laravel + Vue.
my question is how to import the javascript files to my current component.
basically, i want to convert the HTML code below to a component.
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="refresh" content="60">
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>Armenia Map</title>
<script src="data.js"></script>
<script src="country.js"></script>
</head>
<body>
<h1></h1>
<div id="map"></div>
</body>
</html>
This is my Compoent:
<template>
<div id="map"></div>
</template>
<script>
import * from '../plugins/country';
import * from '../plugins/map';
export default {
mounted(){
}
}
</script>
please if someone can help.
Thank you.
Depending on what you want to import, you can also do something like this:
import { mapGetters } from 'vuex'
const Countries = require('../plugins/country')
If the file contains javascript code you want to execute emidietely you can do like with bootstrap.js and just require the file.
require('./bootstrap')

When a new component is inserted all the rest disappears inside the app

I always build my SPA apps with the vue-cli.
This time I'm building a small project and I'm incluing Vue with a script tag.
But I don't understand the following behavior.
// app.js
Vue.component('todo-item', {
template: `<div>Todo Component!</div>`
})
var app = new Vue({
el: '#app',
data: {
message: 'Hello Vue App!'
}
})
The HTML index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Title</title>
</head>
<body>
<div id="app">
{{ message }}
<div>
Just some content...
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="./js/app.js"></script>
</body>
</html>
The result is this:
Now, I'll try to add '<todo-item />' Component inside the HTML:
<div id="app">
{{ message }}
<todo-item />
<div>
Just some content...
</div>
</div>
The text 'Just some content...' disappeared:
What Am I doing wrong?
TL;DR;
instead of <todo-item/> use <todo-item></todo-item>
Un-compiled vue.js does not support self-closing html tags.
see style guide:
Unfortunately, HTML doesn’t allow custom elements to be self-closing -
only official “void” elements. That’s why the strategy is only
possible when Vue’s template compiler can reach the template before
the DOM, then serve the DOM spec-compliant HTML.
https://v2.vuejs.org/v2/style-guide/#Self-closing-components-strongly-recommended
and issues in github:
https://github.com/vuejs/vue/issues/1036
https://github.com/vuejs/vue/issues/8664