ruigomeseu / vue-turnstile

A Cloudflare Turnstile library for Vue 3
MIT License
63 stars 9 forks source link

How to access reset method in vue 3 component? #1

Closed CreativeWarlock closed 1 year ago

CreativeWarlock commented 1 year ago

Hi mate,

really love your plugin, thanks for all the hard work you've put into it!

I've got a question as I haven't been able to access the reset() method of the VueTurnstile component. Here's what I tried so far:

<template>
<div>
    ...
   <Form v-slot="{ errors }" :validationSchema="schema" @submit="submitData">
    <div class="form-row py-2">
        <div class="form-group col-md-8 offset-2">
            <label for="email"><strong>Email Address</strong></label>
            <Field id="email" as="input" name="email" type="email" autocomplete="email"
                class="form-control" />
            <small v-if="errors.email" class="text-danger">{{ errors.email }}</small>
        </div>
    </div>
    <div class="form-row py-2">
        <div class="form-group col-md-8 offset-2">
            <label for="password"><strong>Password</strong></label>
            <Field id="password" as="input" name="password" type="password"
                autocomplete="current-password" class="form-control" />
            <small v-if="errors.password" class="text-danger">{{
                errors.password
            }}</small>
        </div>
    </div>

    <div class="form-row py-2">
        <div class="form-group col-md-8 offset-2">
            <VueTurnstile ref="turnstile" :reset="resetTurnstile" :site-key="sitekey" v-model="token" />
        </div>
    </div>

    <div class="form-row">
        <div class="form-group col-md-8 offset-2">
            <div class="d-grid">
                <button class="btn bg-vue btn-secondary">
                    <span v-if="!isLoading">Log in</span>
                    <span v-else class="spinner-border spinner-border-sm" />
                </button>
            </div>
        </div>
    </div>
</Form>
</div>
</template>

<script>
import { usePageStore } from '@/stores/page-store'
import { useUserStore } from '@/stores/user-store'
import { Form, Field } from 'vee-validate'
import * as yup from 'yup'
import VueTurnstile from 'vue-turnstile';

export default {
    // eslint-disable-next-line vue/multi-word-component-names
    name: 'Login',
    components: {
        // eslint-disable-next-line vue/no-reserved-component-names
        Form,
        Field,
        VueTurnstile
    },
    data() {
        const schema = yup.object().shape({
            email: yup.string().required('Email address required.').trim().email('This is no valid email address.'),
            password: yup.string().required('Password required.').min(6, 'Password must be at least 6 characters long.')
        })
        const sitekey = 'xxx'

        return {
            email: '',
            errorMsg: '',
            isLoading: false,
            schema,
            sitekey,
            token: ''
        }
    },
    methods: {
        submitData(values) {
            console.log("Submitting values to doSignIn:", values)
            console.log("Submitting verifyToken:", this.token)
            this.errorMsg = ''
            this.isLoading = true
            useUserStore()
                .doSignIn({
                    email: values.email,
                    password: values.password,
                    verifyToken: this.token
                })
                .then(async (loggedInUser) => {
                    console.log('Login successful for user:', loggedInUser)
                    this.$emit('close')

                    await usePageStore().resetPageStore()

                    if (useUserStore().isUserAdmin) {
                        this.$router.push({ path: '/admin' })
                    } else {
                        this.$router.push({ path: '/my-account' })
                    }
                })
                .catch((error) => {
                    console.log("Received error:", error)
                    this.errorMsg = error.message
                    console.log("Resetting turnstile widget...", this.$refs.turnstile)
                    this.$refs.turnstile.reset() // not this.$parent.$refs.turnstile
                })
                .finally(() => {
                    this.isLoading = false
                })
        }
    }
}

Maybe you got an idea how to access the reset() method in this Vue 3 component?

CreativeWarlock commented 1 year ago

Turns out, this.$parent.$refs.turnstile needed to be replaced with this.$refs.turnstile.reset() and it's working.