|
1 | 1 | <template>
|
2 |
| - <div :id="elementId" |
3 |
| - ></div> |
| 2 | + <div :id="id"></div> |
4 | 3 | </template>
|
5 | 4 |
|
6 | 5 | <script>
|
7 | 6 | export default {
|
8 | 7 | name: 'google-recaptcha-v3',
|
9 | 8 | props: {
|
10 |
| - siteKey: { |
| 9 | + action: { |
11 | 10 | type: String,
|
12 |
| - required: true |
| 11 | + required: false, |
| 12 | + default: 'validate_grecaptcha' |
13 | 13 | },
|
14 |
| - elementId: { |
| 14 | + id: { |
15 | 15 | type: String,
|
16 |
| - required: true |
| 16 | + required: false, |
| 17 | + default: 'grecaptcha_container' |
| 18 | + }, |
| 19 | + siteKey: { |
| 20 | + type: String, |
| 21 | + required: false, // set to true if you don't want to store the siteKey in this component |
| 22 | + default: '' // set siteKey here if you want to store it in this component |
17 | 23 | },
|
18 | 24 | inline: {
|
19 | 25 | type: Boolean,
|
20 |
| - default: false |
| 26 | + required: false, |
| 27 | + default: false, |
21 | 28 | },
|
22 |
| - action: { |
23 |
| - type: String, |
24 |
| - required: true |
25 |
| - } |
26 | 29 | },
|
27 | 30 | data() {
|
28 | 31 | return {
|
29 |
| - gAssignedId: null, |
30 |
| - captchaReady: false, |
31 |
| - renderedReady: false, |
32 |
| - checkInterval: null, |
33 |
| - checkIntervalRunCount: 0 |
| 32 | + captchaId: null, |
34 | 33 | }
|
35 | 34 | },
|
36 |
| - created() { |
37 |
| - }, |
38 |
| - computed: {}, |
39 | 35 | mounted() {
|
40 | 36 | this.init();
|
41 | 37 | },
|
42 |
| - watch: { |
43 |
| - captchaReady: function (data) { |
44 |
| - if (data) { |
45 |
| - clearInterval(this.checkInterval) |
46 |
| - this.render() |
47 |
| - } |
48 |
| - }, |
49 |
| - renderedReady: function (data) { |
50 |
| - if (data) { |
51 |
| - clearInterval(this.checkInterval) |
52 |
| - this.execute() |
53 |
| - } |
54 |
| - }, |
55 |
| - }, |
56 | 38 | methods: {
|
57 |
| - execute() { |
58 |
| - let action = this.action; |
59 |
| - window.grecaptcha.ready(function () { |
60 |
| - grecaptcha.execute(this.gAssignedId, { |
61 |
| - action: action |
62 |
| - }); |
63 |
| - }); |
| 39 | + init() { |
| 40 | + if (!('grecaptcha' in window)) { |
| 41 | +
|
| 42 | + window.gRecaptchaOnLoad = this.render; |
| 43 | +
|
| 44 | + let recaptchaScript = document.createElement('script'); |
| 45 | + recaptchaScript.setAttribute('src', 'https://www.google.com/recaptcha/api.js?render=explicit&onload=gRecaptchaOnLoad'); |
| 46 | + recaptchaScript.async = true; |
| 47 | + recaptchaScript.defer = true; |
| 48 | + document.head.appendChild(recaptchaScript); |
| 49 | +
|
| 50 | + } else { |
| 51 | + this.render(); |
| 52 | + } |
64 | 53 | },
|
| 54 | +
|
65 | 55 | render() {
|
66 |
| - this.gAssignedId = window.grecaptcha.render(this.elementId, { |
| 56 | + this.captchaId = window.grecaptcha.render(this.id, { |
67 | 57 | sitekey: this.siteKey,
|
68 | 58 | badge: this.inline === true ? 'inline' : '',
|
69 |
| - size: 'invisible' |
| 59 | + size: 'invisible', |
| 60 | + 'expired-callback': this.execute |
70 | 61 | });
|
71 |
| - this.renderedReady = true; |
| 62 | +
|
| 63 | + this.execute(); |
72 | 64 | },
|
73 |
| - init() { |
74 |
| - this.checkInterval = setInterval(() => { |
75 |
| - this.checkIntervalRunCount++; |
76 |
| - if (window.grecaptcha && window.grecaptcha.hasOwnProperty('render')) { |
77 |
| - this.captchaReady = true |
78 |
| - } else { |
79 |
| - let recaptchaScript = document.createElement('script'); |
80 |
| - recaptchaScript.setAttribute('src', 'https://www.google.com/recaptcha/api.js?render=explicit'); |
81 |
| - document.head.appendChild(recaptchaScript); |
82 |
| - recaptchaScript.async = true; |
83 |
| - recaptchaScript.defer = true; |
84 |
| - } |
85 |
| - }, 1000) |
| 65 | +
|
| 66 | + execute() { |
| 67 | + window.grecaptcha.execute(this.captchaId, { |
| 68 | + action: this.action, |
| 69 | + }).then((token) => { |
| 70 | + this.$emit('input', token); |
| 71 | + }); |
86 | 72 | }
|
87 | 73 | }
|
88 | 74 | }
|
|
0 commit comments