Vue3-ts报错:类型“never”上不存在属性“resetFields“

本文讲述了在Vue3项目中使用TypeScript时,遇到关于表单验证的错误,即在`never`类型的`formRef.value`上找不到`resetFields`属性。解决方案是初始化`formRef`为`ref()`而非`ref(null)`。示例展示了如何在注册登录组件中处理这个问题。
摘要由CSDN通过智能技术生成

Vue3-ts报错:类型“never”上不存在属性“resetFields“

在 Vue3 项目中使用表单的时候,通常有验证环节,在 script 中:

const showModal = ref(false);
const isRegistering = ref(false); // 新增状态
const formRef = ref(null);
const formState = ref({
    username: '',
    password: '',
    repeatPassword: '' // 仅在注册时使用
});

const handleSubmit = () => {
    if (formRef.value) {
        formRef.value.validate((errors: any) => {
            if (!errors) {
                console.log('提交的数据', formState.value);
                // 在这里添加提交表单的逻辑
            }
        });
    } else {
        console.error('表单数据不存在');
    }
};

const handleReset = () => {
    if (formRef.value) {
        formRef.value.resetFields();
    } else {
        console.error('表单数据不存在');
    }
};

此时会出现报错:

类型“never”上不存在属性“resetFields“

问题原因

const formRef = ref(null);

此时formRef.value 的类型是 never ,要避免这个错误,将 ref 的初始值改为空即可。

解决方式

修改formRef

const formRef = ref();

完整代码(简单的注册登录组件)

<template>
    <div class="container">
        <n-modal v-model:show="showModal" title="登录/注册">
            <div class="form">
                <p>欢迎使用Promptate</p>
                <n-form ref="formRef" :model="formState" :rules="rules">
                    <n-form-item label="用户名" path="username">
                        <n-input v-model:value="formState.username" placeholder="请输入用户名" />
                    </n-form-item>
                    <n-form-item label="密码" path="password">
                        <n-input v-model:value="formState.password" placeholder="请输入密码" type="password" />
                    </n-form-item>
                    <!-- 注册时添加重复密码字段 -->
                    <n-form-item v-if="isRegistering" label="重复密码" path="repeatPassword">
                        <n-input v-model:value="formState.repeatPassword" placeholder="请再次输入密码" type="password" />
                    </n-form-item>
                    <div class="btnGroup">
                        <n-button @click="handleSubmit">{{ isRegistering ? '注册' : '登录' }}</n-button>
                        <n-button @click="handleReset">重置</n-button>
                    </div>
                </n-form>
                <div class="toggle-action" @click="toggleForm">
                    {{ isRegistering ? '已有账号?登录' : '没有账号?注册' }}
                </div>
            </div>
        </n-modal>
        <n-button @click="showModal = true" class="btn">登录/注册</n-button>
    </div>
</template>
  
<script setup lang="ts">
import { ref } from 'vue';
const showModal = ref(false);
const isRegistering = ref(false); // 新增状态
const formRef = ref();
const formState = ref({
    username: '',
    password: '',
    repeatPassword: '' // 仅在注册时使用
});

// 根据当前模式(登录/注册)调整验证规则
const rules = ref({
    username: {
        required: true,
        message: '请输入用户名',
        trigger: 'blur'
    },
    password: {
        required: true,
        message: '请输入密码',
        trigger: 'blur'
    },
    repeatPassword: isRegistering.value ? {
        required: true,
        message: '请再次输入密码',
        trigger: 'blur'
    } : {}
});

const handleSubmit = () => {
    if (formRef.value) {
        formRef.value.validate((errors: any) => {
            if (!errors) {
                console.log('提交的数据', formState.value);
                // 在这里添加提交表单的逻辑
            }
        });
    } else {
        console.error('表单数据不存在');
    }
};

const handleReset = () => {
    if (formRef.value) {
        formRef.value.resetFields();
    } else {
        console.error('表单数据不存在');
    }
};

const toggleForm = () => {
    isRegistering.value = !isRegistering.value;
};
</script>

<style scoped lang="scss">
.btn {
    margin-left: 10px;
}

.container {
    display: flex;
    align-items: center;
    text-align: center;
}

p {
    text-align: center;
    font-size: 20px;
}

.form {
    background-color: white;
    width: 400px;
    padding: 20px 50px;
    border-radius: 5px;
    box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); 
}

.btnGroup {
    display: flex;
    justify-content: center;
    gap: 16px; /* 这会在按钮之间创建16px的间隙 */
}

.toggle-action {
    margin-top: 20px;
    text-align: center;
    color: #409eff;
    cursor: pointer;
}
</style>
  • 9
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值