MST
星途 面试题库

面试题:Svelte表单自定义验证规则与性能优化

在一个大型Svelte项目的用户资料编辑表单中,需要对多个复杂字段进行验证。比如,有一个“出生日期”字段,要求输入格式为YYYY - MM - DD,并且要确保出生日期在1900年1月1日到当前日期之间;还有一个“身份证号码”字段,要根据中国身份证号码的校验规则进行验证(包括地址码、出生日期码、顺序码和校验码的全面验证)。请描述如何设计可复用的自定义验证函数,如何将这些验证规则高效地应用到表单中,并且在表单数据频繁变化的情况下,如何进行性能优化以避免不必要的重新渲染。
21.7万 热度难度
前端开发Svelte

知识考点

AI 面试

面试题答案

一键面试

1. 设计可复用的自定义验证函数

  • 出生日期验证函数
function validateBirthdate(date) {
    const datePattern = /^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])$/;
    if (!datePattern.test(date)) return false;
    const inputDate = new Date(date);
    const minDate = new Date('1900-01-01');
    const currentDate = new Date();
    return inputDate >= minDate && inputDate <= currentDate;
}
  • 身份证号码验证函数
function validateIdCard(idCard) {
    // 地址码校验(这里简化处理,不详细列出所有地区码)
    const addressCodePattern = /^\d{6}/;
    if (!addressCodePattern.test(idCard)) return false;
    // 出生日期码校验
    const birthdateCode = idCard.substring(6, 14);
    const birthdate = `${birthdateCode.substring(0, 4)}-${birthdateCode.substring(4, 6)}-${birthdateCode.substring(6, 8)}`;
    if (!validateBirthdate(birthdate)) return false;
    // 顺序码校验(简单判断为数字)
    const sequenceCodePattern = /^\d{3}/;
    if (!sequenceCodePattern.test(idCard.substring(14, 17))) return false;
    // 校验码校验
    const weights = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
    const validators = ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'];
    let sum = 0;
    for (let i = 0; i < 17; i++) {
        sum += parseInt(idCard.charAt(i), 10) * weights[i];
    }
    const mod = sum % 11;
    return idCard.charAt(17) === validators[mod];
}

2. 将验证规则应用到表单

在Svelte中,可以在表单元素的bind:value时结合验证函数。例如:

<script>
    let birthdate = '';
    let idCard = '';
    let birthdateError = '';
    let idCardError = '';

    function handleSubmit() {
        if (!validateBirthdate(birthdate)) {
            birthdateError = '出生日期格式不正确或不在指定范围内';
        }
        if (!validateIdCard(idCard)) {
            idCardError = '身份证号码不正确';
        }
        if (!birthdateError &&!idCardError) {
            // 提交表单逻辑
        }
    }
</script>

<form on:submit|preventDefault={handleSubmit}>
    <label>出生日期:</label>
    <input type="text" bind:value={birthdate} />
    {#if birthdateError}
        <p style="color: red">{birthdateError}</p>
    {/if}
    <label>身份证号码:</label>
    <input type="text" bind:value={idCard} />
    {#if idCardError}
        <p style="color: red">{idCardError}</p>
    {/if}
    <button type="submit">提交</button>
</form>

3. 性能优化避免不必要的重新渲染

  • 防抖(Debounce): 对于表单输入频繁变化的情况,可以使用防抖函数。在Svelte中,可以封装一个防抖函数:
function debounce(func, delay) {
    let timer;
    return function() {
        const context = this;
        const args = arguments;
        clearTimeout(timer);
        timer = setTimeout(() => {
            func.apply(context, args);
        }, delay);
    };
}

const debouncedValidate = debounce(handleSubmit, 300);

然后在表单输入事件中调用debouncedValidate,这样可以在用户停止输入300毫秒后才执行验证,减少不必要的重新渲染。

  • 节流(Throttle): 如果希望在用户输入过程中定期验证,可以使用节流函数。例如:
function throttle(func, delay) {
    let lastCall = 0;
    return function() {
        const now = new Date().getTime();
        if (now - lastCall >= delay) {
            func.apply(this, arguments);
            lastCall = now;
        }
    };
}

const throttledValidate = throttle(handleSubmit, 500);

在表单输入事件中调用throttledValidate,这样每隔500毫秒执行一次验证,也能有效控制重新渲染频率。