Vuejs:vuelidate 条件验证

Vuejs: vuelidate conditional validation

假设我们有一个密码字段,我们想要对长度、特殊字符、数字、大写和小写等进行一些验证,仅当该字段具有值时

我们如何使用 vuelidate 做到这一点。

我在这里导入vuelidate

import { required, minLength, maxLength, email, sameAs } from 'vuelidate/lib/validators'

这里是验证

validations: {
    editedItem: {
      firstname: { required, minLength: minLength(3), maxLength: maxLength(20) },
      lastname: { required, minLength: minLength(3), maxLength: maxLength(20) },
      email: { required, email },
      password: {
        required,
        minLength: minLength(6),
        maxLength: maxLength(15),
        oneNumber,
        oneUpperCase,
        oneLowerCase,
      },
      repassword: {
        sameAsPassword: sameAs('password'),
      },
    },
  }

,

oneNumber、oneUpperCase 和 oneLowerCase 是自定义验证:

const oneNumber = (value) => /[0-9]/.test(value)
const oneUpperCase = (value) => /[A-Z]/.test(value)
const oneLowerCase = (value) => /[a-z]/.test(value)

我将永远感激任何帮助或建议

我的解决方案涉及一个单独的“自定义验证器”文件。

validators.js:

import { helpers as vuelidateHelpers } from 'vuelidate/lib/validators'

export const oneUppercase = value => {
  if (!vuelidateHelpers.req(value)) {
    return true
  }
  const match = value.match(/[A-Z]/g) || []
  return match.length >= 1
}
export const oneLowercase = value => {
  if (!vuelidateHelpers.req(value)) {
    return true
  }
  const match = value.match(/[a-z]/g) || []
  return match.length >= 1
}
export const oneSpecial = value => {
  if (!vuelidateHelpers.req(value)) {
    return true
  }
  const match = value.match(/[ !@#$%^&*()_+\-=[\]{};':"\|,.<>/?]/g) || []
  return match.length >= 1
}
export const oneNumber = value => {
  if (!vuelidateHelpers.req(value)) {
    return true
  }
  const match = value.match(/\d/g) || []
  return match.length >= 1
}

在组件中,通过可视化格式让用户知道他们的密码是否符合要求:

<template>
  <form>
    <label for="password">Password</label>
    <input
            id="password"
            name="password"
            type="password"
            v-model="form.password"
            @blur="$v.form.password.$touch()"
            @input="validatePassword"
    />
    <label for="confirmPassword">Confirm Password</label>
    <input
            id="confirmPassword"
            name="confirmPassword"
            type="password"
            v-model="form.confirmPassword"
            @blur="$v.form.confirmPassword.$touch()"
    />
    <ul>
      <li>
          {{
          passwordValidations.eightCharacters ?
          '✓':
          '╳'
          }}
        <span class="ml-1">MUST contain 8 characters</span>
      </li>
      <li>
          {{
          passwordValidations.oneUppercase ?
          '✓':
          '╳'
          }}
        <span class="ml-1">MUST contain one uppercase letter</span>
      </li>
      <li>
          {{
          passwordValidations.oneLowercase ?
          '✓':
          '╳'
          }}
        <span class="ml-1">MUST contain one lowercase letter</span>
      </li>
      <li>
          {{
          passwordValidations.oneNumber ?
          '✓':
          '╳'
          }}
        <span class="ml-1">MUST contain one number</span>
      </li>
      <li>
          {{
          passwordValidations.oneSpecial ?
          '✓':
          '╳'
          }}
        <span class="ml-1">MUST contain one special character</span>
      </li>
    </ul>
  </form>
</template>

<script>
  import {
    required,
    minLength,
    sameAs,
  } from 'vuelidate/lib/validators'
  import {
    oneNumber,
    oneSpecial,
    oneUppercase,
    oneLowercase,
  } from '../validators'

  export default {
    data () {
      return {
        form: {
          password: '',
          confirmPassword: '',
        },
        passwordValidations: {
          eightCharacters: false,
          oneUppercase: false,
          oneLowercase: false,
          oneNumber: false,
          oneSpecial: false,
        },
      }
    },
    computed: {
      passwordErrors () {
        const errors = []
        if (!this.$v.form.password.$dirty) return errors
        !this.$v.form.password.required && errors.push('Password is required.')
        return errors
      },
      confirmPasswordErrors () {
        const errors = []
        if (!this.$v.form.confirmPassword.$dirty) return errors
        !this.$v.form.confirmPassword.required && errors.push('Please confirm your password.')
        !this.$v.form.confirmPassword.sameAsPassword && errors.push('Passwords don\'t match')
        return errors
      },
    },
    methods: {
      validatePassword () {
        this.passwordValidations.eightCharacters = this.$v.form.password.eightCharacters
        this.passwordValidations.oneUppercase = this.$v.form.password.oneUppercase
        this.passwordValidations.oneLowercase = this.$v.form.password.oneLowercase
        this.passwordValidations.oneNumber = this.$v.form.password.oneNumber
        this.passwordValidations.oneSpecial = this.$v.form.password.oneSpecial
      },
    },
    validations: {
      form: {
        password: {
          required,
          minLength: minLength(8),
          oneUppercase,
          oneSpecial,
          oneNumber,
          oneLowercase,
        },
        confirmPassword: {
          required,
          sameAsPassword: sameAs('password'),
        },
      },
    },
  }
</script>