Vue with a form validator via CDN but can't render the form elements

64 views Asked by At

I need to use Vue with a form validator via CDN but I can't render the form elements, the code below is a simple form with just one field in the input but Vue doesn't render the form element, I've already lost several hours trying to find it the problem.

<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script src="https://unpkg.com/vee-validate"></script>
<div id="app">
    

    <Form @submit="onSubmit">
        <Field name="email" type="email" :rules="validateEmail"></Field>
        <ErrorMessage name="email"></ErrorMessage>
        <button>Sign up</button>
    </Form>


</div>

<script>
    const {ErrorMessage, Field, Form} = "vee-validate";

    const {createApp, ref} = Vue

    createApp({
        setup() {
        }, components: {
            Form,
            Field,
            ErrorMessage,
        },
        methods: {
            onSubmit(values) {
                console.log(values, null, 2);
            },
            validateEmail(value) {
                // if the field is empty
                if (!value) {
                    return 'This field is required';
                }
                // if the field is not a valid email
                const regex = /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i;
                if (!regex.test(value)) {
                    return 'This field must be a valid email';
                }
                // All is good
                return true;
            },
        },
    }).use(VeeValidate).mount('#app')
</script>

1

There are 1 answers

4
Moritz Ringler On BEST ANSWER

You are pretty much there, only few things are off:

  • vee-validate is not a plugin, remove the .use(VeeValidate)
  • The global object is VeeValidate (or window.VeeValidate), so you have to destructure from there instead of vee-validate:
const {ErrorMessage, Field, Form} = VeeValidate;
  • If you want to use the original HTML as template, you have to take care of in-dom template caveats. So you cannot use Form, as it will end up as a regular <form> element, you have to rename it or use is="vue:Form", and you have to specify the other components in kebap case (error-message, etc.).

Here it is in a snippet:

const { createApp, ref } = Vue;
const {ErrorMessage, Field, Form} = VeeValidate;

const App = {
  components: {
      Form,
      Field,
      ErrorMessage,
  },
  methods: {
      onSubmit(values) {
          console.log(values, null, 2);
      },
      validateEmail(value) {
          // if the field is empty
          if (!value) {
              return 'This field is required';
          }
          // if the field is not a valid email
          const regex = /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i;
          if (!regex.test(value)) {
              return 'This field must be a valid email';
          }
          // All is good
          return true;
      },
  },
}
const app = createApp(App)
app.mount('#app')
<div id="app">
    <form is="vue:Form" @submit="onSubmit">
        <Field name="email" type="email" :rules="validateEmail"></Field>
        <error-message name="email"></error-message>
        <button>Sign up</button>
    </form>
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script src="https://unpkg.com/vee-validate"></script>