【问题标题】:Vue.js vuelidate: How to debounce async custom validator?Vue.js vuelidate:如何去抖动异步自定义验证器?
【发布时间】:2018-08-17 04:10:32
【问题描述】:

我有一个验证器来检查用户名是否已经在数据库中注册。它工作得很好,除了这个事实,请求是在输入每个字符的情况下发送到服务器的——这是经常发生的。所以我试图去抖动用户名变量值的设置,但我得到的只是:

Uncaught TypeError: Cannot read property 'value' of undefined 
at a.NHnr.q.methods.debounceUsername.H.a.debounce.leading

Vue 脚本:

import uniqueUsername from '../validation/uniqueUsername'
import _ from 'lodash'

export default {
    name: "signUpPage",
    data() {
      return {
        credentials: {
          username: ''
        }
      }
    },
    methods: {
      debounceUsername:
        _.debounce(function (e) {
          this.credentials.username = e.target.value;
        }, 200, {leading: false, trailing: true})
    },
    validations: {
      credentials: {
        username: {
          uniqueUsername: uniqueUsername
        }
      }
   }
}

HTML:

    <b-field :label="msg('usernameLabel')"
             :class="{ 'form-group--error': $v.credentials.username.$error }">
      <b-input size="is-large" type="text" class="form__input"
               icon="account" name="username" v-on:input="debounceUsername" autofocus="">
      </b-input>
    </b-field> 
//b-field and b-input are from buefy library

自定义验证器(uniqueUsername.js):

import axios from 'axios'

export default value => {
  if (value.trim().length === 0) return true;
  let usernameUnique;
  return new Promise(async function (resolve) {
    await axios('/isUsernameUnique', {
      method: "post",
      data: value,
      headers: {'Content-type': 'text/plain'}
    }).then((response) => usernameUnique = response.data);
    if (usernameUnique) resolve('username is unique');
  });
};

【问题讨论】:

    标签: javascript vue.js lodash vuelidate


    【解决方案1】:

    一种解决方案是检查用户何时专注于输入字段(模糊),然后运行异步验证。所以:

    <input @blur="$v.username.$touch" v-model.lazy="username" />
    

    脚本:

    export default {
      data () {
       return {
        username: ''
       }
      },
      validations: {
        username: {
         required,
         isUnique(username) {
           if (username === '') return true
           return axios.get('/checkUsername')
                     .then(res => {
                       return res.data //res.data has to return true or false after checking if the username exists in DB
                     }) 
         }
        }
      }
    }
    

    注意:要使用此代码,您必须从 vuelidate 导入 axios 和必需

    还要记住。如果用户名是唯一的,则后端必须返回 false 才能使上述代码正常工作

    【讨论】:

    • 不过,如果您想提供实时更新,那将是糟糕的用户体验 — 用户现在必须跳出该字段以查看用户名是否已被使用,然后再返回以更改它。
    【解决方案2】:

    我找到了答案。 我不得不改变

    this.credentials.username = e.target.value;
    

    到:

    this.credentials.username = e;
    

    它现在可以工作了——发送请求的频率现在最多每 200 毫秒一次

    【讨论】:

      猜你喜欢
      • 2019-03-23
      • 1970-01-01
      • 2019-03-15
      • 1970-01-01
      • 1970-01-01
      • 2020-02-22
      • 2023-03-12
      • 2017-10-26
      • 1970-01-01
      相关资源
      最近更新 更多