Closed SAntoineS closed 2 months ago
It seems to work if I bind the v-model
on the FormField
and not directly on the Input
.
Don't create new ref
for values, componentField
slotProp already have model-value
and @update:model-value
(v-model).
Instead use initialValues
(useForm) option or :initial-values
(Form) prop
https://stackblitz.com/edit/1d3tzs-8cmpb1?file=src%2FApp.vue
Don't create new
ref
for values,componentField
slotProp already havemodel-value
and@update:model-value
(v-model).Instead use
initialValues
(useForm) option or:initial-values
(Form) prophttps://stackblitz.com/edit/1d3tzs-8cmpb1?file=src%2FApp.vue
Oooh ok cool !
So I can access to the values via values.uniteLocale.idea
, like :
watch(() => values.uniteLocale.ide,
(newValue) => {
console.log('New Value: ', newValue);
}
);
And it works!
Thanks a lot !
How can I pass the values to child component, it's like a ref
?
Because in my context I have a stepper (with two steps) inside the form and each steps is a component.
It's a form application with fields into the steps.
In Stepper it's better to use Form
component instead of useForm
composable just like this link
https://www.shadcn-vue.com/docs/components/stepper.html#form
So you could access the Form
context wherever you want with passing props
or using inject
or using vee-validate
utilities
In Stepper it's better to use
Form
component instead ofuseForm
composable just like this linkhttps://www.shadcn-vue.com/docs/components/stepper.html#form
So you could access the
Form
context wherever you want withpassing props
or usinginject
or usingvee-validate
utilities
I am sorry but I can't understand how to do this...
This is my Form
:
<Form v-slot="{ meta, values, validate }" as="" keep-values
:validation-schema="toTypedSchema(formSchema[stepIndex - 1])">
<Stepper v-slot="{ isNextDisabled, isPrevDisabled, nextStep, prevStep }" v-model="stepIndex"
class="block w-full">
<form @submit.prevent="HandleSubmit(meta, values, validate)">
<div class="flex w-full flex-start gap-2">
<StepperItem
v-for="step in steps"
:key="step.step"
v-slot="{ state }"
class="relative flex w-full flex-col items-center justify-center"
:step="step.step">
<StepperSeparator
v-if="step.step !== steps[steps.length - 1].step"
class="absolute left-[calc(50%+20px)] right-[calc(-50%+10px)] top-5 block h-0.5 shrink-0 rounded-full bg-muted group-data-[state=completed]:bg-primary"/>
<StepperTrigger as-child>
<Button
:variant="state === 'completed' || state === 'active' ? 'default' : 'outline'"
size="icon"
class="z-10 rounded-full shrink-0"
:class="[state === 'active' && 'ring-2 ring-ring ring-offset-2 ring-offset-background']"
:disabled="state !== 'completed' && !meta.valid">
<Check v-if="state === 'completed'" class="size-5"/>
<component v-if="state === 'active' || state === 'inactive'" :is="step.icon" class="w-4 h-4"/>
</Button>
</StepperTrigger>
<div class="mt-5 flex flex-col items-center text-center">
<StepperTitle
:class="[state === 'active' && 'text-primary']"
class="text-sm font-semibold transition lg:text-base">
{{ step.title }}
</StepperTitle>
<StepperDescription
:class="[state === 'active' && 'text-primary']"
class="sr-only text-xs text-muted-foreground transition md:not-sr-only lg:text-sm">
{{ step.description }}
</StepperDescription>
</div>
</StepperItem>
</div>
<div class="flex flex-col gap-4 mt-20">
<step-inscription v-if="stepIndex === 1"/>
<step-responsable v-if="stepIndex === 2"/>
</div>
<!-- Step Actions -->
<div class="flex items-center justify-between mt-4">
<Button :disabled="isPrevDisabled" variant="ghost" size="sm" @click="prevStep()">
Précédent
</Button>
<!-- Next or Submit Actions -->
<div class="flex items-center gap-3">
<Button variant="informationTonal" v-if="stepIndex !== 2" :type="meta.valid ? 'button' : 'submit'"
:disabled="isNextDisabled"
size="sm" @click="meta.valid && nextStep()">
Suivant
</Button>
<Button variant="successTonal"
v-if="stepIndex === 2" size="sm" type="submit">
Soumettre
</Button>
</div>
</div>
</form>
</Stepper>
</Form>
How can I use inject
from vue with values
(Inside the Form
)
I want to modify / access (like watch()
) values
in my child components.
I can't pass with this :
<step-inscription v-model="values" v-if="stepIndex === 1"/>
cause Vue don't want v-slot
scope variable in v-model
.
Like this error :
Internal server error: v-model cannot be used on v-for or v-slot scope variables because they are not writable.
Can you share a minimal demo of your Stepper component
I can't help in this way
Can you share a minimal demo of your Stepper component
I can't help in this way
Sure !
There is a stackblitz of a minimal demo of my project.
I'm currently using v-model
on FormField
and provide (then inject in child) my object like this in main.vue
:
const uniteLocale = ref<any>({});
provide('uniteLocale', uniteLocale);
I saw in the Vee Validate documentation that we can use v-model
. I don't know if there is a cleaner method to access to Form
values from outside the Form
.
Inside <Form>
component you can use useFormValues
vee-validate composable
Outside <Form>
component
ref
on the form component and access the values in script section like formRef.value.values
or in template like formRef.values
Even though the vee-validate docs says you can use v-model
on FormField
it is better not to do it
I tried with ref
like :
const uniteLocale = ref<any>({});
provide('uniteLocale', uniteLocale);
----------------------------------------------
<Form v-slot="{ meta, validate }" :initial-values="formValuesUniteLocale" keep-values
:validation-schema="toTypedSchema(formSchema[stepIndex - 1])" ref="uniteLocale">
In my child component I have a watch()
that works :
const uniteLocale = inject<Ref>("uniteLocale");
----------------------------------------------
watch(() => uniteLocale.value.values?.descriptionActiEconomiques, (newValue) => {
isDescriptionFilled.value = !!newValue;
});
The only issue I have left is that I can't modify the value directly from the code like this :
function importIDE(uniteLegal) {
if (uniteLegal) {
try {
const { value } = useField('ide');
value.value = "test1"
uniteLocale.value.values.ide = "test2"
toast({
title: 'Entreprise importée avec succès ! ✅',
variant: 'default',
});
} catch (e) {
console.error("Erreur lors de l'importation UniteLegal -", e)
toast({
title: "Oops ! Erreur lors de l'importation ❌",
variant: 'default',
});
}
}
console.log("UniteLocale.ide: ", uniteLocale.value.values.ide);
}
I tried with directly changing the variable and tried with useField
method of vee-validate
.
No one works...
But I have this vue-warn :
[Vue warn] Set operation on key "ide" failed: target is readonly.
Do you know why ? I have to contact directly vee-validate
?
Sorry for the deep discussion : /
Thanks a lot !
The only issue I have left is that I can't modify the value directly from the code like this :
You need to use
uniteLocale.value.setFieldValue('idle or object.idle', 'new value')
//or
uniteLocale.value.setValues({
idle: 'new value',
// or
'object.idle': 'new value'
})
uniteLocale.value.setFieldValue('idle or object.idle', 'new value')
It works fine !
Thanks a lot for all your help !
can somebody explain whats the point of adding these extra step instead of binding a ref to the input field? what benefit is there to not being able to bind to the input field?
can somebody explain whats the point of adding these extra step instead of binding a ref to the input field? what benefit is there to not being able to bind to the input field?
VeeValidate FormField slotProps already have model-value and @update:model-value (componentField slotProp), which is why it's better to use initialValues with componentField slotProp so we could also get a better resetForm functionality and get right types
Reproduction
https://stackblitz.com/edit/1d3tzs-zd6u8m?file=src%2FApp.vue
Describe the bug
Description:
I am experiencing an issue with the
v-model
binding not updating the input value in theInput
component from Shadcn-vue inside aForm
. Even though the value changes in the parent component, the input field in the child component doesn't reflect the updated value.Steps to reproduce:
Input.vue
):Expected behavior:
The input field should update its value when
uniteLocale.ide
is modified programmatically.Actual behavior:
The value in the input field does not update even though the value of
uniteLocale.ide
changes.What I’ve tried:
passive: true
option fromuseVModel
.uniteLocale.ide
is being updated correctly by logging it and displaying it in a<span>
.watch
to observe changes tomodelValue
and emitupdate:modelValue
accordingly.Despite these changes, the input field does not reflect the updated value.
Additional context:
useVModel
from@vueuse/core
appears to work in other components, but here it doesn't update the input value as expected. Thespan
displayinguniteLocale.ide
is updated correctly, but not the input field.Thanks !
System Info
Contributes