Home > OS >  How can I access Vuetify v-form ref in VueJS using Composition API at <script setup>?
How can I access Vuetify v-form ref in VueJS using Composition API at <script setup>?

Time:07-02

I'm creating a form using Vuetify's v-form in Vue using their Composition API and <script setup>. Using v-form's rules, I've created a way to validate user input; however, once the form is submitted, I need to clear the form's fields. When the fields are reset (using empty strings), the form rules are triggered and validation errors appear. I would like to access v-form's built-in functions (e.g., clear()); however, I can't access this.$refs.form in <script setup>. How can I access these functions or just clear my form without triggering validation rule errors after submission?

Here is the script portion so far:

<script setup lang="ts">
import { ref, Ref } from 'vue'
import { Service } from '@/types/service'

const service: Ref<Service> = ref({ name: '', endpoint: '' })
const loading = ref(false)
const isValid = ref(true)

const register = () => {
  loading.value = true
  isValid.value = false
  clear()
  setTimeout(() => {
    loading.value = false
  }, 2000)
}

const clear = () => {
  service.value = { name: '', endpoint: '' }
}

const serviceNameRules = [
  (v: string) => !!v || 'Service name is required',
  (v: string) =>
    v.length <= 20 || 'Service name must be less than 20 characters',
]

const endpointRules = [
  (v: string) => v.length <= 100 || 'Endpoint must be less than 100 characters',
  (v: string) =>
    isURL(v) ||
    'Endpoint must have a valid URL format (i.e., "http://example.com")',
]

const isURL = (str: string) => {
  try {
    const url = new URL(str)
    return url.protocol === 'http:' || url.protocol === 'https:'
  } catch (_) {
    return false
  }
}
</script>

Here is my template form

<template>
  <v-card elevation="5">
    <v-progress-linear
      v-if="loading"
      
      style="z-index: 1"
      color="#0062B8"
      height="10"
      indeterminate
    />

    <v-card-title>Register New Service</v-card-title>
    <v-card-text>
      <v-form
        @submit.prevent="register()"
        v-model="isValid"
        ref="form"
        lazy-validation
      >
        <v-text-field
          v-model="service.name"
          label="Service Name"
          hint="e.g., 'service-pages'"
          :rules="serviceNameRules"
          required
        />
        <v-text-field
          v-model="service.endpoint"
          label="Endpoint"
          hint="https://www.example.com/page"
          :rules="endpointRules"
          required
        />
        <v-btn
          type="submit"
          color="#0062B8"
          style="color: white"
          :disabled="!isValid"
        >
          Register
        </v-btn>
      </v-form>
    </v-card-text>
  </v-card>
</template>

CodePudding user response:

Try to create a form ref inside your script which is automatically bound to ref="form":

<script setup lang="ts">
import { ref, Ref } from 'vue'
import { Service } from '@/types/service'

const service: Ref<Service> = ref({ name: '', endpoint: '' })
const loading = ref(false)
const isValid = ref(true)

const form=ref<HTMLFormElement>(null)

....
 // then use it like 
 if(form.value){
     form.value.reset()
  }
 //or
  form.value?.reset()
....

  • Related