Understanding why Element UI event handlers are triggering RangeError: Maximum call stack size exceeded?

Understanding why Element UI event handlers are triggering RangeError: Maximum call stack size exceeded?

我目前正在尝试设置一个表单并使用 Element UI 对其进行验证。到目前为止,我已经非常仔细地遵循了文档,它加载正常,但是一旦您单击并在输入框中键入内容,或者单击提交表单按钮,它就会导致 RangeError:超出最大调用堆栈大小。

我已经尝试过调试,但它似乎只在事件触发时发生。 In 似乎在没有输入时正确进入所有验证函数,但一旦输入,它已经卡在循环中,所以我似乎无法获得这部分。

<template>
    <el-container class="card">
        <el-form ref="form" :model="form" :rules="rules" :label-position="labelPosition" size="small">
            <label>Username</label>
            <el-form-item size="small" prop="name">
                <el-input class="form-input" v-model="form.name"></el-input>
            </el-form-item>
            <label>Password</label>
            <el-form-item prop="password" size="small">
                <el-input class="form-input" v-model="form.password" type="password"  autocomplete="off"></el-input>
            </el-form-item>
            <el-form-item>
                <el-button class="form-button" type="primary" size="small" @click="submitForm('form')">Submit</el-button>
            </el-form-item>
        </el-form>
    </el-container>
</template>

<script>
    export default {
        name: "LoginPage",
        data () {
            let validateName = (rule, value, callback) => {
                if (value === '') {
                    callback(new Error('Please input valid username'));
                } else {
                    if (this.form.name !== '') {
                        this.$refs.form.validateField('name');
                    }
                    callback();
                }
            };
            let validatePassword = (rule, value, callback) => {
                if (value === '') {
                    callback(new Error('Please input valid password'));
                } else {
                    if (this.form.password !== '') {
                        this.$refs.form.validateField('password');
                    }
                    callback();
                }
            };
            return {
                labelPosition: 'top',
                form: {
                    name: '',
                    password: '',
                },
                rules: {
                    name: [
                        { validator: validateName, trigger: 'blur' },
                        { min: 2, max: 15, message: 'Length should be between 2 to 15', trigger: 'blur' }
                    ],
                    password: [
                        { validator: validatePassword, trigger: 'blur' }
                    ]
                }
            }
        },
        methods: {
            submitForm(formName) {
                this.$refs[formName].validate((valid) => {
                    if (valid) {
                        alert('yes');
                    } else {
                        return false;
                    }
                });
            }
        }
    }
</script>

错误示例:

在框中单击带有内容的按钮:"click" 的事件处理程序出错:"RangeError: Maximum call stack size exceeded"

在输入框中输入内容并点击离开时:"el.form.blur" 的事件处理程序出错:"RangeError: Maximum call stack size exceeded"

如果您查看 ElementUI 文档中的 examples,您会发现它们使用 setTimeout 来实现自定义规则以限制调用规则的次数。在您的情况下,一旦该字段具有值(因此, if 情况为假),您的 else 块就会一遍又一遍地执行,直到它超过最大调用堆栈大小。您可以像这样限制对自定义规则的调用来解决此问题:

export default {
  name: "LoginPage",
  data () {
    let validateName = (rule, value, callback) => {
      if (value === '') {
        return callback(new Error('Please input valid username'));
      }
      setTimeout(() => {
        if (this.form.name !== '') {
          this.$refs.form.validateField('name');
        }
        callback();
      }, 1000);
    };
    let validatePassword = (rule, value, callback) => {
      if (value === '') {
        return callback(new Error('Please input valid password'));
      }
      setTimeout(() => {
        if (this.form.password !== '') {
          this.$refs.form.validateField('password');
        }
        callback();
      }, 1000);
    };
    return {
      labelPosition: 'top',
      form: {
        name: '',
        password: '',
      },
      rules: {
        name: [
          { validator: validateName, trigger: 'blur' },
          { min: 2, max: 15, message: 'Length should be between 2 to 15', trigger: 'blur' }
        ],
        password: [
          { validator: validatePassword, trigger: 'blur' }
        ]
      }
    }
  },
  methods: {
    submitForm(formName) {
      this.$refs[formName].validate((valid) => {
        if (valid) {
          alert('yes');
        } else {
          return false;
        }
      });
    }
  }
}