Pengikatan model v pada medan pemilih tarikh saya tidak berfungsi dengan betul.
Apabila anda membuat pilihan, ia akan dikemas kini secara langsung pada skrin tetapi ia tidak akan menyimpan nilai dalam objek reaktif formValues.
Memandangkan vee-validate tidak menyokong medan pemilih tarikh, bagaimanakah cara saya memaksanya untuk mengemas kini kepada komponen tindak balas yang sama (formValues) yang mana semua medan input saya yang lain dipetakan.
<template> <img alt="Vue logo" src="./assets/logo.png"> <div v-if="showUnderAge.isVisible"> SORRY WE CANT HELP UNDER 18 </div> <div v-if="showOutOfCountry.isVisible"> SORRY WE CANT HELP OUT OF COUNTRY </div> <div v-if="showContainer.isVisible"> <h1>Create your Account</h1> Verify Entry values: <br /> {{ formValues }} <Form @submit="nextStep" :validation-schema="currentSchema" v-slot="{ handleSubmit }" > <template v-if="currentStep === 0"> <label for="name">Name</label> <Field name="name" id="name" v-model="formValues.name" /> <ErrorMessage name="name" /> <br /> <label for="email">Email</label> <Field name="email" id="email" type="email" v-model="formValues.email" /> <ErrorMessage name="email" /> <br /> <label for="country">Country</label> <Field as="select" name="country" v-model="formValues.country"> <option value="United States">United States</option> <option value="Canada">Canada</option> <option value="-" disabled>---------------</option> <option value="Afghanistan">Afghanistan</option> <option value="Åland Islands">Åland Islands</option> <option value="Albania">Albania</option> <option value="Algeria">Algeria</option> <option value="American Samoa">American Samoa</option> <option value="Andorra">Andorra</option> <option value="Angola">Angola</option> <option value="Anguilla">Anguilla</option> <option value="Antarctica">Antarctica</option> <option value="Antigua and Barbuda">Antigua and Barbuda</option> </Field> <br /> <label for="dob">Date of Birth</label> <Datepicker autoApply name="dob" v-model="formValues.date" :enableTimePicker="false" style="width: 20%"></Datepicker> <br /> </template> <template v-if="currentStep === 1"> <label for="password">Password</label> <Field name="password" type="password" id="password" v-model="formValues.password" /> <ErrorMessage name="password" /> <label for="confirmation">Confirm Password</label> <Field name="confirmPassword" type="password" id="confirmation" v-model="formValues.password" /> <ErrorMessage name="confirmPassword" /> </template> <template v-if="currentStep === 2"> <label for="address">Address</label> <Field as="textarea" name="address" id="address" v-model="formValues.address" /> <ErrorMessage name="address" /> <label for="postalCode">Postal Code</label> <Field name="postalCode" id="postalCode" v-model="formValues.postalCode" /> <ErrorMessage name="postalCode" /> </template> <template v-if="currentStep === 3"> <label for="terms">Agree to terms and conditions</label> <Field name="terms" type="checkbox" id="terms" :value="true" v-model="formValues.terms" /> <ErrorMessage name="terms" /> </template> <button v-if="currentStep !== 0" type="button" @click="prevStep"> Previous </button> <button v-if="currentStep !== 3" type="submit">Next</button> <button v-if="currentStep === 3" type="submit">Finish</button> </Form> </div> </template> <script> import { Form, Field, ErrorMessage } from "vee-validate"; import * as yup from "yup"; import { ref, reactive, computed } from "vue"; import Datepicker from 'vue3-date-time-picker'; import 'vue3-date-time-picker/dist/main.css'; import moment from 'moment'; export default { name: "App", components: { Form, Field, ErrorMessage, Datepicker }, setup: () => { const currentStep = ref(0); // since vee-validate removes values from the values object once the fields are unmounted // we would need to accumlate them manually const formValues = reactive({}); const showContainer = ref({isVisible: true}); const showOutOfCountry = ref({isVisible: false}); const showUnderAge = ref({isVisible: false}); const schemas = [ yup.object({ name: yup.string().required(), email: yup.string().required().email(), }), yup.object({ password: yup.string().required().min(6), confirmPassword: yup .string() .required() .min(6) .oneOf([yup.ref("password")], "Passwords must match"), }), yup.object({ address: yup.string().required(), postalCode: yup .string() .required() .matches(/^[0-9]+$/, "Must be numeric"), }), yup.object({ terms: yup.bool().required().equals([true]), }), ]; const currentSchema = computed(() => { return schemas[currentStep.value]; }); function getAge(dateString){ var today = new Date(); var birthDate = new Date(dateString); var age = today.getFullYear() - birthDate.getFullYear(); var m = today.getMonth() - birthDate.getMonth(); if (m < 0 || (m === 0 && today.getDate() < birthDate.getDate())) { age--; } return age; } function nextStep(values) { console.log(currentStep.value) console.log(values) // Age kickout here for entire block let dobDt = moment(values.dob).format("YYYY-MM-DD"); console.log(dobDt) let age = getAge(dobDt) console.log(age) if(age < 18){ showUnderAge.value.isVisible = true; showContainer.value.isVisible = false; }else{ // Country Kick Out console.log(values.country) if(values.country !== "United States"){ showOutOfCountry.value.isVisible = true; showContainer.value.isVisible = false; console.log(showContainer) return; }else{ // Last Step if (currentStep.value === 3) { console.log("Done: ", JSON.stringify(formValues, null, 2)); return; } // accumlate the form values with the values from previous steps Object.assign(formValues, values); console.log("Current values: "); console.log(JSON.stringify(formValues, null, 2)); currentStep.value++; } } } function prevStep() { if (currentStep.value <= 0) { return; } currentStep.value--; } return { currentStep, currentSchema, prevStep, formValues, nextStep, showContainer, showOutOfCountry, showUnderAge }; }, }; </script> <style> #app { font-family: Avenir, Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; } .appContainer{ max-width: 800px; margin: 30px auto; overflow: auto; min-height: 300px; padding: 30px; border-radius: 5px; border-style: solid; border-width: 1px; border-color: rgb(109, 109, 109); } label{ font-weight: bold; } .validationErrors{ color: red; font-weight: bold; } </style>
Ada dua cara untuk menyelesaikan masalah ini. Nota: Anda boleh menggunakan mana-mana pemilih tarikh yang anda suka. Pertama:
Untuk maklumat lanjut, lihat dokumentasi vee-validate. Berikut ialah pautan: https://vee-validate.logaretm.com/v4/api/field/