VeeValidate with Yup:输入类型="number" 值在提交时转换为字符串

VeeValidate with Yup: input type="number" value is converted to string on submit

我使用 VeeValidate 和 Yup 进行表单验证,但不知道为什么我的类型为“number”的输入字段在提交时被转换为字符串。

当我输入 78 并提交表单时,onSubmit(values) 函数中 console.log 的输出如下:

values: {
   prioritaet: "78"
}

我是不是做错了什么或者这是 VeeValidate 和 Yup 的正常行为?我想在提交后得到一个数字而不是字符串。

我的代码如下所示:

<template>
  <div class="container m-3">
    <div class="row bg-primary align-items-center py-2">
      <div class="col">
        <h3 class="text-light mb-0">Format {{ this.action }}</h3>
      </div>
      <div class="col-auto">
        <h5 class="text-light mb-0">{{ this.formatTitle }}</h5>
      </div>
    </div>

    <Form @submit="onSubmit" :validation-schema="formatSchema" v-slot="{ errors }" ref="formatForm">
      <div class="row mt-4">
        <div class="col">
          <h5>Formatdaten</h5>
        </div>
      </div>

      <div class="row mb-2">
        <div class="col-4">
          <label for="prioritaet-input">Priorität: </label>
        </div>
        <div class="col">
          <Field type="number" name="prioritaet" id="prioritaet-input" class="w-100" />
        </div>
      </div>

      <div class="row justify-content-end">
        <div class="col-auto me-auto">
          <button class="btn btn-outline-primary">Änderungen übernehmen</button>
        </div>
        <div class="col-auto">
          <button class="btn btn-outline-primary">Abbrechen</button>
        </div>
        <div class="col-auto">
          <button type="sumbit" class="btn btn-outline-primary">Speichern</button>
        </div>
      </div>
      
      <div class="row mt-4">
        <template v-if="Object.keys(errors).length">
          <span class="text-danger" v-for="(message, field) in errors" :key="field">{{ message }}</span>
        </template> 
      </div>
    </Form>

  </div>
</template>
<script>
import { Form, Field } from "vee-validate";
import deLocale from "../assets/yup-localization.js";
import * as Yup from "yup";
import { markRaw } from "vue";

import { mapActions, mapState } from "vuex";

Yup.setLocale(deLocale);

export default {
  name: "FormatBearbeitungsSchirm",
  props: ["material_id"],
  data() {
    let action = "neu";
    let formatTitle = "Format neu";

    let formatSchema = markRaw(Yup.object().shape({
      prioritaet: Yup.number().min(1).max(100).integer().label("Priorität"),
    }));

    return { formatSchema, action, formatTitle };
  },
  created() {

  },
  components: {
    Form,
    Field,
  },
  methods: {
    onSubmit(values) {
      console.log("values", values);
    },
  },
};
</script>

您必须使用 .number 修饰符。

你可以阅读它here

If you want user input to be automatically typecast as a Number, you can add the number modifier to your v-model managed inputs:

const app = new Vue({
  el: "#app",
  data: () => ({
      mynumber1: undefined,
      mynumber2: undefined
  }),
  methods: {
    submit() {
      console.log(typeof this.mynumber1, this.mynumber1)
      console.log(typeof this.mynumber2, this.mynumber2)
    }
  }
})
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
<div id="app">
  <form>
  <!-- number modifier -->
 <input type="number" v-model.number="mynumber1" placeholder="Type here" />
  <!-- no modifier -->
 <input type="number" v-model="mynumber2" placeholder="Type here" />
 <input type="button" @click="submit" value="submit" />
 </form>
</div>

目前似乎不支持在 <Field> 的内部字段模型值上指定 .number 修饰符,因此发出的表单 values 将始终包含一个字符串number-类型字段。

一种解决方法是转换模板中的值,更新 <Form>'s values slot prop in <Field>'s update:modelValue event:

<Form @submit="onSubmit" v-slot="{ values }">
  <Field                             
    type="number"
    name="prioritaet"      
    @update:modelValue="values.prioritaet = Number(values.prioritaet)"
  />

  <button>Submit</button>
</Form>

demo

另一个简单的解决方法是在使用前转换 onSubmit 中的 属性:

export default {
  onSubmit(values) {
    values.prioritaet = Number(values.prioritaet)

    // use values here...
  }
}