Replies: 3 comments
-
Here is my best attempt... <template>
<h2>My Form</h2>
<form>
Field 1:
<Field name="field1" />
<ErrorMessage name="field1" />
<br />
Field 2:
<Field name="field2" />
<ErrorMessage name="field2" />
</form>
</template>
<script setup lang="ts">
import {ErrorMessage, Field, useForm} from "vee-validate";
import {object, string} from "yup";
import {toRef} from "vue";
const props = defineProps({
modelValue: {type: Object, required: true}
})
const emit = defineEmits(['update:modelValue']);
const model = toRef(props, 'modelValue');
const schema = object({
field1: string().required().max(15),
field2: string().required().max(15)
})
const form = useForm({initialValues: model, validationSchema: schema})
const submit = () => {
form.validate().then((r) => {
if (r.valid) {
// I wish I could use the klona function, is this possible?
model.value.field1 = form.values.field1
model.value.field2 = form.values.field2
emit('update:modelValue', model.value)
}
})
}
const reset = () => {
form.resetForm()
}
defineExpose({submit, reset})
</script> <template>
<h1>Vee Validate Submit Button</h1>
<MyForm ref="myForm" v-model="model" />
<button @click="submit">Submit</button>
<button @click="reset">Reset</button>
</template>
<script setup lang="ts">
import MyForm from './components/MyForm.vue';
import {ref} from "vue";
const model = ref({field1: 'Hello', field2: 'World'})
const myForm = ref<InstanceType<typeof MyForm> | null>(null) // template ref
const submit = () => {
myForm.value?.submit()
}
const reset = () => {
myForm.value?.reset()
}
</script> |
Beta Was this translation helpful? Give feedback.
-
I would say you should go for HOC approach here with scoped slots. Make your component offer a spot where buttons can be added via a named slot and offer the submit functions on the slot. So something like this: <template>
<h2>My Form</h2>
<form>
Field 1:
<Field name="field1" />
<ErrorMessage name="field1" />
<br />
Field 2:
<Field name="field2" />
<ErrorMessage name="field2" />
</form>
<!-- It is fine to be outside the form if that's what you want -->
<slot name="afterForm" :submit="submit" :reset="reset" />
</template> Then it can be used like this: <template>
<h1>Vee Validate Submit Button</h1>
<MyForm>
<template #afterForm="{ submit, reset }">
<button @click="submit">Submit</button>
<button @click="reset">Reset</button>
</template>
</MyForm>
</template> |
Beta Was this translation helpful? Give feedback.
-
Thanks for your answer (and apologies for the delayed mine). It is indeed much more elegant and an approach I will definitely keep in my mind. My example was an over simplification. What I am trying to solve is slightly more complex. I need the parent component to be able to decide where to display the buttons, even outside the MyForm component, for example in a global toolbar. I will experiment with Vue teleport and your suggested approach. <template>
<h1>Vee Validate Submit Button</h1>
<div id="buttons"></div>
<MyForm>
<template #afterForm="{ submit, reset }">
<teleport to="#buttons">
<button @click="submit">Submit</button>
<button @click="reset">Reset</button>
</teleport>
</template>
</MyForm>
</template> |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
Hello,
I would like to be able to reuse my forms and their logic a different places of my application. To do so, I need to define the submit/reset buttons outside of the form component. I successfully implemented a solution with
useForm
declaration in the parent component (see below). I am using Vue 3, VeeValidate 4.6 and yup 1.0.0-beta.However, my solution pulls the methods for submit and reset outside of the form component, and in turn the schema. I would rather keep all inside the form component so I do not have to declare those again when reusing the form. The only way I can think of is abusing template refs and probably dealing with an updateValue event for the model property.
Is there an elegant vee-validate way of achieving the level reuse of the form with its logic while moving the buttons around?
Many thanks!
Beta Was this translation helpful? Give feedback.
All reactions