Skip to content

VeeField "intercepting" values from multiple v-models of component #5097

@samupl

Description

@samupl

What happened?

I have a custom QuotaInput component which is meant to abstract a text input and an unit selector to type a file size:

<template>
  <div>
    <input type="number" placeholder="quota" v-model="value" />
    <select placeholder="unit" v-model="unit">
      <option value="GB">GB</option>
      <option value="MB">MB</option>
    </select>
  </div>
</template>

<script setup>
import { ref, onMounted, watch } from 'vue';

const model = defineModel();
const props = defineProps({
  disabled: Boolean,
  value: String,
  showUnitInDom: Boolean,
});
const value = ref(0);

const multipliers = {
  KB: 1 / 1024,
  MB: 1,
  GB: 1024,
};
const unit = ref('MB');

onMounted(() => {
  value.value = model.value || 0;
});

watch([unit, value], () => {
  console.log('watch');
  model.value = value.value * (multipliers[unit.value] || 1);
});
</script>

Key points:

  • There is one model defined via defineModel() - this is what the "consumer" of the component can use
  • Internally, the component uses a value field and it updates the model accordingly with the converted value.

This component seems to work fine on its own. However when used in a VeeField inside a zod vee-validate form, suddenly the value gets taken from both inputs.

What's even weirded is that when I displayed {{ unit }} in the QuotaInput in my "real" project, the issue went away. As soon as {{ unit }} is not rendered anywhere, the issue comes back. For some reason I could not reproduce this behaviour on stackblitz.

I prepared a stackblitz with the issue reproduction. Navigate to the "bug reproduction" page.

Reproduction steps

  1. Write a custom component like the one above
  2. Use it in a vee-validate/zod typed schema
  3. Observe the bug

Version

Vue.js 3.x and vee-validate 4.x

What browsers are you seeing the problem on?

  • Firefox - only if input is empty
  • Chrome - always
  • Safari - always
  • Microsoft Edge

Relevant log output

Demo link

https://stackblitz.com/edit/vitejs-vite-v4kj5i6j?file=src%2Fcomponents%2FQuotaInput.vue

Code of Conduct

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions