Vuejs typing into input with v-model directive removes a CSS class somehow

250 Views Asked by At

So I have a form with multiple input fields, whenever I type something into these fields, somehow it manipulates the DOM, and removes a certain class active from the form container. Please see this GIF to see it.

Steps to reproduce:

  1. Click create your account
  2. Type anything in any of the shown field
  3. Observe the faulty behavior (which is the result of removing the active class)

Template code:

        // active class is getting injected here
        <div class="login-forms__container">
          <section class="new-user__section">
            <form>
              <h1>{{ $t('login.create-form.title') }}</h1>
              <p>{{ $t('login.create-form.subtitle') }}</p>
              <b-field>
                <b-input
                  v-model="registerForm.fullName"
                  :placeholder="$t('login.create-form.name')"
                  type="text"
                  icon-pack="fas"
                  icon="user"
                  maxlength="25"
                />
              </b-field>

              ....

              <div class="field">
                <small>
                  <a target="_blank" @click.prevent="toggleCreateAccount">
                    {{ $t('login.create-form.registered') }}
                  </a>
                </small>
              </div>
            </form>
          </section>
        </div>

JS code:

    methods: {
      toggleCreateAccount () {
        document
          .querySelector('.login-forms__container')
          .classList
          .toggle('active');
      },

What I've tried:

  • Disable/Enable hot reloading
  • Tracing DOM event listeners (through breakpoints)
  • Changing the class name (suspected that "active" name is too common and might get removed by other libraries)
  • Using e.preventDefault() and click.prevent;
  • Or even removing the function responsible for adding the class and inject the class manually through inspect elements

Note:- removing v-model fixes the issue

1

There are 1 best solutions below

0
On BEST ANSWER

You're modifying the DOM manually in a way that Vue can't trace. When it comes time to rerender, it sees the class you added, but since it doesn't match the VDOM in the template (you don't have "active" in your template), it thinks it must be removed (VDOM = source of truth).

You should conditionally include the active class in your template, Vue will automatically patch the DOM for you.

An abbreviated example:

template: `<div :class="{'.login-forms__container': true, active: createAccountActive }">`,

data() {
  createAccountActive: false,
},

methods: {
  toggleCreateAccount() {
    this.createAccountActive = !this.createAccountActive;
  }
},