Search code examples
vue.jsdatepickervue-componentvuejs3default-value

Vue Datepicker wont show default date onrender


I have a Vue app which is loading another component that implements a range date field using vue-datepicker. I want it to have a default range of last 7 days when it first renders.

However, I can't set the data to it on render, even though I am passing it to the component via :value attribute.

My date picker component code:

<template>
    <div>
        <Datepicker
            v-model="selectedDates"
            type="range"            
            :value="[startDate, endDate]"
            @change="onDateChange"
            range            
            :enable-time-picker="false"
            format="MMM dd"
        />
    </div>
</template>

<script>
import Datepicker from "@vuepic/vue-datepicker"

export default {
    components: {
        Datepicker,
    },
    data() {
        return {
            selectedDates: [this.startDate, this.endDate],
            startDate: new Date(new Date().setDate(new Date().getDate() - 7)),
            endDate: new Date(),
        }
    },
    methods: {
        onDateChange() {
            this.$emit("date-change", this.selectedDates)
        },
    },
}
</script>

There are no errors in browser console, either.


Solution

  • You can't define data props based on other data props directly. You can define the value for your prop directly by using:

    <template>
        <div>
            <Datepicker range
                v-model="selectedDates"
                @change="onDateChange"         
                :enable-time-picker="false"
                format="MMM dd" />
        </div>
    </template>
    
    <script>
        import Datepicker from "@vuepic/vue-datepicker"
    
        export default {
            components: {
                Datepicker,
            },
            data() {
                return {
                    selectedDates: [new Date(new Date().setDate(new Date().getDate() - 7)), new Date()],
                }
            },
            methods: {
                onDateChange() {
                    this.$emit("date-change", this.selectedDates)
                },
            },
        }
    </script>
    

    Note that we now don't reference other properties when defining selectedDates.

    Or you can use computed properties, which is cleaner in my opinion:

    <template>
        <div>
            <Datepicker range
                v-model="selectedDates"
                @change="onDateChange"         
                :enable-time-picker="false"
                format="MMM dd" />
        </div>
    </template>
    
    <script>
        import Datepicker from "@vuepic/vue-datepicker"
    
        export default {
            components: {
                Datepicker,
            },
            computed: {
                startDate() {
                    return new Date(new Date().setDate(new Date().getDate() - 7));
                },
                endDate() {
                    return new Date();
                },
                selectedDates() {
                    return [this.startDate, this.endDate]
                }
            }
            methods: {
                onDateChange() {
                    this.$emit("date-change", this.selectedDates)
                },
            },
        }
    </script>
    

    Also note that you bind to both v-model and :value. I would suggest only binding to v-model.