VueJS中多个相同date-time-picker子组件仅绑定最后一个值的问题排查与解决
Hey there,
Let me break down your problem and walk you through the fixes:
First, let's pinpoint the root cause
This is almost always a parent component binding logic issue, especially when you're rendering multiple date-time-picker instances (like your two numbered components). It's rare for the child component itself to cause shared bindings unless it's incorrectly using global/non-isolated state. The most common culprit is reusing the same data variable for all child components instead of giving each its own independent source.
Step-by-step fixes
1. Fix the parent component's data binding
If you're using v-for to render your pickers, you might be binding all of them to a single variable (like selectedDate). That's why only the last component's value sticks—they're all writing to the same piece of state.
Wrong approach:
<date-time-picker v-for="(item, index) in 2" v-model="selectedDate" /> // Parent component data data() { return { selectedDate: null // All pickers share this single value } }
Correct approach: Use an array/object to store independent values for each picker:
<date-time-picker v-for="(item, index) in 2" :key="index" v-model="selectedDates[index]" /> // Parent component data data() { return { selectedDates: [null, null] // Initialize empty values for each picker } }
For better readability (especially if these are start/end dates), use an object instead:
<date-time-picker v-for="pickerType in ['start', 'end']" :key="pickerType" v-model="selectedDates[pickerType]" /> // Parent component data data() { return { selectedDates: { start: null, end: null } } }
2. Add a unique key to your v-for
Vue uses the key attribute to track component instances. Without a unique key, Vue might reuse component instances incorrectly, leading to unexpected state sharing. Always use a unique identifier (like the index, or a specific type string as above) for each item in the loop.
3. Verify your child component's v-model implementation
If the parent binding looks correct but you still have issues, check your date-time-picker child component to ensure it properly handles two-way binding with b-form-input:
For Vue 2:
<template> <b-form-input type="datetime-local" :value="value" @input="$emit('input', $event.target.value)" /> </template> <script> export default { props: { value: { type: String, // Matches datetime-local's string value format default: null } } } </script>
For Vue 3:
<template> <b-form-input type="datetime-local" v-model="localValue" /> </template> <script setup> import { ref, watch } from 'vue' const props = defineProps({ modelValue: { type: String, default: null } }) const emit = defineEmits(['update:modelValue']) const localValue = ref(props.modelValue) // Sync local changes to parent watch(localValue, (newVal) => { emit('update:modelValue', newVal) }) // Sync parent changes to local watch(() => props.modelValue, (newVal) => { localValue.value = newVal }) </script>
Make sure your child component isn't using any global variables or shared internal state—this would cause all instances to sync to the same value.
Quick recap
- Use independent data variables for each picker in the parent
- Add a unique
keyto yourv-forloop - Ensure the child component correctly implements two-way binding without shared state
内容的提问来源于stack exchange,提问作者Leonardo H

