Home > Software design >  which would be the correct way to toggle this boolean prop in Vue?
which would be the correct way to toggle this boolean prop in Vue?

Time:08-14

So I'm quite new with vue, currently working with Vue3 TypeScript. I was told to make an input validation on an email required field, I used the pattern property from the element and fire a disable class from CSS:

input:invalid ~ .triggerError {
  display: block;}

which enables a span with a message if the pattern is not correct. I have one problem, I want to fire this message after onBlur event, so I'm basically toggling a boolean value which is a local component Prop. Here's the code:

     <input
                
                type="email"
                :placeholder="t('contact.email')"
                v-model="email"
                @blur="focused = !focused"
                required
                pattern="^[a-zA-Z0-9.!#$%&'* /=?^_`{|}~-] @[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$"
              />
              <span v-if="focused" 
                >It should be a valid email address!</span
              >

<script lang="ts">
import { defineComponent, ref } from 'vue'
import axios from 'axios'
import { useReCaptcha } from 'vue-recaptcha-v3'
import { useI18n } from 'vue-i18n'

export default defineComponent({
  name: 'Form',
  props: {
    focused: {
      type: Boolean,
      default: true
    }
  },

<style>
.triggerError {
  color: red;
  display: none;
}

input:invalid[focused='true'] ~ .triggerError {
  display: block;
}
</style>

enter image description here

error: (property) focused: any
Cannot assign to 'focused' because it is a read-only property.ts(2540)
Unexpected mutation of "focused" prop.eslintvue/no-mutating-props

CodePudding user response:

Like the error message is saying: you cannot change the state of the prop, the prop state is handled by the parent. If you want to have a 'normal' reactive variable local to the scope of the current component, just use data e.g.:

  <input
                
                type="email"
                :placeholder="t('contact.email')"
                v-model="email"
                @blur="focused = !focused"
                required
                pattern="^[a-zA-Z0-9.!#$%&'* /=?^_`{|}~-] @[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$"
              />
              <span v-if="focused" 
                >It should be a valid email address!</span
              >

<script lang="ts">
import { defineComponent, ref } from 'vue'
import axios from 'axios'
import { useReCaptcha } from 'vue-recaptcha-v3'
import { useI18n } from 'vue-i18n'

export default defineComponent({
  name: 'Form',
  data() {
    return {
      focused: true
    }
  },

<style>
.triggerError {
  color: red;
  display: none;
}

input:invalid[focused='true'] ~ .triggerError {
  display: block;
}
</style>

Then you can change the state of the reactive variable focused

  • Related