7
votes

I am working on Vue.js template and on the sign up page, I need to compare password while user signup so, I added custom validation rule like the following code:

<v-text-field 
    label="Password" 
    v-model="password" 
    :rules="passwordRules" 
    type="password" 
    required
></v-text-field>
<v-text-field 
    label="Confirm Password" 
    v-model="confirmPassword" 
    :rules="[confirmPasswordRules,passwordConfirmationRule]"
    type="password" 
    required
></v-text-field>

script:

data() {
    return {
        password: "",
        confirmPassword: "",
        passwordRules: [v => !!v || "Password is required"],
        confirmPasswordRules: [v => !!v || "Password is required"],
    };
},

Compare password method in computed:

computed: {
    passwordConfirmationRule() {
        return () => (this.password === this.confirmPassword) || 'Password must match'
    },
}

I use the computed method for confirm password its working fine and compare the password perfectly but it shows error in console [Vuetify] Rules should return a string or boolean, received 'object' instead so how can I solve this ??

4

4 Answers

6
votes

You're getting the error message because the rules property of the "Confirm Password" input doesn't contain a one-dimensional array containing the rules, but instead contains confirmPasswordRules which is an array itself plus the passwordConfirmationRule rule.

So essentially this

:rules="[confirmPasswordRules, passwordConfirmationRule]"

contains this:

:rules="[[v => !!v || "Password is required"], (this.password === this.confirmPassword) || 'Password must match']"

You want all of the rules to be contained in a single array instead. You can use the concat method to add the passwordConfirmationRule to the confirmPasswordRules array like this:

:rules="confirmPasswordRules.concat(passwordConfirmationRule)" 

I've created a Codepen to show that this works here.

6
votes

you can use

template :

<v-text-field
  v-model="password"
  label="Password"
  name="password"
  prepend-icon="mdi-lock"
  type="password"
  :rules="passwordRules"
/>

<v-text-field
  v-model="confirmPassword"
  label="Confirm Password"
  name="confirmPassword"
  prepend-icon="mdi-lock"
  type="password"
  :rules="confirmPasswordRules"
/>

script:

data() {
    return {
      password: '',
      confirmPassword: '',
      passwordRules: [
        (value) => !!value || 'Please type password.',
        (value) => (value && value.length >= 6) || 'minimum 6 characters',
      ],
      confirmPasswordRules: [
        (value) => !!value || 'type confirm password',
        (value) =>
          value === this.password || 'The password confirmation does not match.',
      ],
    }
},
1
votes

template

<v-text-field
  label="Password"
  v-model="password"
  :rules="[rules.passwordRules]"
  type="password"
  required>
</v-text-field>
<v-text-field
  label="Confirm Password"
  v-model="confirmPassword"
  :rules="[rules.confirmPasswordRules, passwordConfirmationRule]"
  @update:error="checkPassword"
  type="password"
  required>
</v-text-field>

script

data() {
  return {
    password: "",
    confirmPassword: "",
    validPassword: "",
    rules: {
      passwordRules: v => !!v || "Password is required",
      confirmPasswordRules: v => !!v || "Password is required"
    }
  };
},
methods: {
  checkPassword(invalid) { 
    // correct: false
    if (true == invalid) {
      this.validPassword = false;
    } else {
      this.validPassword = true;
    }
   },
 }

text-field provides an "update:error" event. If the password is valid, it executes a function of that event and returns false. Returns true to a function when it is changed from a valid password to an invalid password.

0
votes

I found another way to solve the problem that I think is worth for anyone coming for a solution.

In my template I have the following:

<v-text-field
   v-model.trim="passwordRepeat"
   label="Confirm Password"
   type="password"
   autocomplete="new-password"
   prepend-icon="mdi-lock-check"
   required
   :rules="repeatPasswordRules"
/>

And in my script section:

computed: {
  repeatPasswordRules() {
    return [
      (v) => !!v || 'Senha não informada',
      (v) => (v && v.length >= 8) || 'A senha deve ter no mínimo 8 caracteres',
      (v) => (v === this.password) || 'Senhas diferentes!',
    ];
  },
},

And of course, don't forget the validation call

validate() {
  const valid = this.$refs.signup.validate();
  if(valid) {      
    //your actions after validation
  }
}