Vue.js中使用jQuery Tempus Dominus日期选择器时v-model不生效求助
Hey there! I’ve dealt with this exact frustration before—when using jQuery-based date pickers like Tempus Dominus in Vue, the v-model doesn’t pick up changes because the plugin modifies the DOM directly, bypassing Vue’s reactive system. Here are the reliable fixes I’ve used:
Core Issue
Tempus Dominus operates on the DOM element’s value property directly, not through Vue’s data binding system. That means Vue can’t detect when the date picker updates the input, so your bound variable stays out of sync.
Solution 1: Manual Event Listening (Quickest Fix)
Initialize the date picker in your component’s mounted hook, then listen for the picker’s native events to update your Vue data manually. Tempus Dominus emits events like change.tempusdominus (when a date is selected) or hide.tempusdominus (when the picker closes)—use these to sync your variable.
Vue 2 Example
<template> <div class="input-group date" id="datePicker"> <input type="text" class="form-control" :value="selectedDate"> </div> </template> <script> import $ from 'jquery'; import 'tempusdominus-bootstrap-4'; // Adjust import based on your version export default { data() { return { selectedDate: '' }; }, mounted() { // Initialize the picker const datePicker = $('#datePicker').tempusDominus({ // Add your config here (e.g., format, minDate) format: 'YYYY-MM-DD' }); // Listen for picker close to update data datePicker.on('hide.tempusdominus', () => { const newDate = $('#datePicker input').val(); this.selectedDate = newDate; // Optional: Convert to Date object if needed // this.selectedDate = new Date(newDate); }); }, beforeDestroy() { // Clean up the picker to avoid memory leaks $('#datePicker').tempusDominus('destroy'); } }; </script>
Vue 3 Setup Example
<template> <div class="input-group date" id="datePicker"> <input type="text" class="form-control" :value="selectedDate"> </div> </template> <script setup> import $ from 'jquery'; import 'tempusdominus-bootstrap-4'; import { ref, onMounted, onBeforeUnmount } from 'vue'; const selectedDate = ref(''); onMounted(() => { const datePicker = $('#datePicker').tempusDominus({ format: 'YYYY-MM-DD' }); datePicker.on('change.tempusdominus', () => { selectedDate.value = $('#datePicker input').val(); }); }); onBeforeUnmount(() => { $('#datePicker').tempusDominus('destroy'); }); </script>
Solution 2: Wrap in a Custom Directive (Cleaner for Reuse)
If you use the date picker across multiple components, create a custom Vue directive to encapsulate the logic:
Vue 3 Directive Example
// In a directives/tempusDominus.js file import $ from 'jquery'; import 'tempusdominus-bootstrap-4'; export default { mounted(el, binding) { const picker = $(el).tempusDominus(binding.value.config || {}); picker.on('change.tempusdominus', () => { const value = $(el).find('input').val(); binding.value.modelValue.value = value; }); }, unmounted(el) { $(el).tempusDominus('destroy'); } };
Use the Directive in Your Component
<template> <div class="input-group date" v-tempus-dominus="{ config: pickerConfig, modelValue: selectedDate }"> <input type="text" class="form-control" :value="selectedDate"> </div> </template> <script setup> import tempusDominus from '@/directives/tempusDominus'; import { ref } from 'vue'; const selectedDate = ref(''); const pickerConfig = { format: 'YYYY-MM-DD', minDate: new Date() }; </script>
Why Your Initial Event Approach Might Have Failed
Double-check that you’re using the correct event names (Tempus Dominus uses namespaced events like hide.tempusdominus, not just hide). Also, make sure you’re listening on the picker instance itself, not just the input element.
内容的提问来源于stack exchange,提问作者Sebastien D

