vue3.0+antd2.x+typescript版的表单组件验证或数据双向绑定失效

3 篇文章 0 订阅

在ant-design-vue2.x版本官网上,虽然支持vue3.0,但目前还是以vue2.x的方式展示组件的使用,并没有对怎么使用vue3.0的组合式API(Composition API)进行展示,导致在项目进行时遇到了好些坑,现将我遇到的问题(表单组件部分)及解决办法做个分享。
表单组件验证和数据双向绑定失效
原写法:

<a-form layout="vertical" :model="form" :rules="formRule" ref="formRef">
   <a-form-item label="用户名" name="username">
      <a-input v-model:value="username" placeholder="请输入用户名">
        <template #prefix><UserOutlined style="color:rgba(0,0,0,.25)"/></template>
      </a-input>
   </a-form-item>
   <a-form-item label="密码" name="username">
      <a-input v-model:value="username" placeholder="请输入密码">
        <template #prefix><LockOutlined style="color:rgba(0,0,0,.25)"/></template>
      </a-input>
   </a-form-item>
 </a-form>
setup() {
    const router = useRouter();
    // ref需要加类型验证,不然在获取formRef.value时会有类型的错误提示
    const formRef= ref<any>(null);
    let formData = reactive({
        username: "",
        password: "",
    });
    let rules = reactive({
        username: [{ required: true, message: "请输入用户名", trigger: "blur"}]
    });
    const onSubmit = () => {
      formRef.value.validate().then((res: object) => {
          router.push({ path: "/" });
        })
        .catch((res: object) => {
          message.error("用户名或密码未填");
        });
    };
    return { ...toRefs(formData), ...toRefs(rules), onSubmit, formRef };

以上写法会导致表单组件不能验证成功,但能绑定数据,于是我换了种绑定数据的写法,reactive返回的是一个对象,在组件中改为

<a-input v-model:value="formData.username" placeholder="请输入用户名"></a-input>

但此时连双向绑定也失效,输入框无法输入,仔细对比了官网案例的写法以及对toRefs方法的官网介绍,原来组件a-form在绑定model和rules时必须是一个对象格式的数据,而通过扩展运算符…toRefs()对外输入的是里面的单个数据,所以还需在里面加一层,即写成:

let formData = reactive({
      form: {username: "", password: ""}
    });

在组件绑定v-model时改为form.username,同理表单验证部分也是一样,完整代码如下:

<template>
  <div class="login_box">
    <div class="content">
      <h3 class="title">**科技后台管理系统</h3>
      <a-form layout="vertical" :model="form" :rules="formRule" ref="formRef">
        <a-form-item label="用户名" name="username">
          <a-input v-model:value="form.username" placeholder="请输入用户名">
            <template #prefix
              ><UserOutlined style="color:rgba(0,0,0,.25)"
            /></template>
          </a-input>
        </a-form-item>
        <a-form-item label="密码" name="password">
          <a-input-password
            v-model:value="form.password"
            placeholder="请输入密码"
          >
            <template #prefix
              ><LockOutlined style="color:rgba(0,0,0,.25)"
            /></template>
          </a-input-password>
        </a-form-item>
        <a-form-item>
          <a-button type="primary" block @click="onSubmit">登 陆</a-button>
        </a-form-item>
        <a-form-item class="flex_box" style="padding:0">
          <router-link class="link_a" to>忘记密码?</router-link>
          <router-link class="link_a" to>注册</router-link>
        </a-form-item>
      </a-form>
    </div>
  </div>
</template>

<script lang="ts">
import { defineComponent, reactive, toRefs, ref } from "vue";
import { UserOutlined, LockOutlined } from "@ant-design/icons-vue";
import { message } from "ant-design-vue";
import { useRouter } from "vue-router";

export default defineComponent({
  name: "login",
  setup() {
    const router = useRouter();
    // ref需要加类型验证,不然在获取formRef.value时会有类型的错误提示
    const formRef= ref<any>(null);
    //表单绑定的数据
    let formData = reactive({
      form: {
        username: "",
        password: "",
      },
    });
    //验证规则
    let rules = reactive({
      formRule: {
        username: [
          { required: true, message: "请输入用户名", trigger: "blur" },
        ],
        password: [
          { required: true, min: 6, message: "密码最少六位", trigger: "blur" },
        ],
      },
    });
    const onSubmit = () => {
      formRef.value.validate().then((res: object) => {
        //验证成功时跳转首页
          router.push({ path: "/" });
        })
        .catch((res: object) => {
        //验证失败提示错误信息
          message.error("用户名或密码未填");
        });
    };
    return { ...toRefs(formData), ...toRefs(rules), onSubmit, formRef };
  },
  components: {
    UserOutlined,
    LockOutlined,
  },
});
</script>

<style scoped lang="less">
.login_box {
  position: relative;
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
  background-color: #283542;
  .link_a {
    color: #666;
    &:hover {
      color: #1890ff;
    }
  }
}
.content {
  width: 340px;
  padding: 20px;
  background-color: #fff;
  border-radius: 2px;
  .title {
    position: relative;
    margin-bottom: 30px;
    font-size: 18px;
    text-align: center;
    &:after {
      content: "";
      position: absolute;
      bottom: -10px;
      left: -20px;
      width: 340px;
      border-bottom: 1px solid #eee;
    }
  }
}
.flex_box :deep(.ant-form-item-children) {
  display: flex;
  justify-content: space-between;
}
</style>

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值