A
A
Alexey2021-12-10 10:53:33
Vue.js
Alexey, 2021-12-10 10:53:33

How to set activePicker in custom component based on v-date-picker?

I am making a custom component for v-date-picker. Ideally: pass the activePicker parameter to choose which picker to use by default. For example, to select a date of birth, use YEAR. But at the moment I can't get the activePicker parameter to work at all.

Here is the component code:

<template>
  <v-menu
    v-model="menu"
    :close-on-content-click="false"
    :nudge-right="40"
    transition="scale-transition"
    offset-y
    min-width="auto"
  >
    <template v-slot:activator="{ on, attrs }">
      <v-text-field
        :value="valueInput"
        :label="label"
        :placeholder="placeholder"
        :hint="hint"
        prepend-icon="mdi-calendar"
        readonly
        dense
        v-bind="attrs"
        v-on="on"
      ></v-text-field>
    </template>
    <v-date-picker
      ref="picker"
      v-model="pickerInput"
      no-title
      :max="maxValue"
      :min="minValue"
      :show-current="showCurrent"
      @input="menu = false"
    ></v-date-picker>
  </v-menu>
</template>

<script>
import { formatDate } from "@/functions"
export default {
  name: "DatePicker",
  props: ['date', 'label', 'hint', 'min', 'max', 'showCurrent', 'placeholder'],
  data () {
    return {
      menu: false
    }
  },
  watch: {
    menu (val) {
      val && setTimeout(() => (this.activePicker = 'YEAR'))
    }
  },
  computed: {
    activePicker: {
      set (newValue) {
        this.$refs.picker.activePicker = newValue
      },
      get: function() {
        return this.$refs.picker.activePicker
      }
    },
    valueInput: {
      set (newValue) {
        this.$emit('update:date', newValue)
      },
      get: function() {
        return formatDate(this.date)
      }
    },
    pickerInput: {
      set (newValue) {
        this.$emit('update:date', newValue)
      },
      get: function() {
        return this.date
      }
    },
    minValue () {
      return this.min || '2021-01-01'
    },
    maxValue () {
      return this.max || null
    }
  }
}
</script>


I run it like this:

...
<Date
  :date.sync="person.birthdate"
  placeholder="Дата рождения"
  :max="new Date().toISOString()"
/>


In console:
[Vue warn]: Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value. Prop being mutated: "activePicker"


What is the ambush? I'm not even passing the parameter that will allow you to set the activePicker yet.

Answer the question

In order to leave comments, you need to log in

1 answer(s)
A
Alexey, 2021-12-10
@alenov

I did this, it works:

<template>
  <v-menu
    v-model="menu"
    :close-on-content-click="false"
    :nudge-right="40"
    transition="scale-transition"
    offset-y
    min-width="auto"
  >
    <template v-slot:activator="{ on, attrs }">
      <v-text-field
        :value="valueInput"
        :label="label"
        :placeholder="placeholder"
        :hint="hint"
        prepend-icon="mdi-calendar"
        readonly
        dense
        v-bind="attrs"
        v-on="on"
      ></v-text-field>
    </template>
    <v-date-picker
      v-model="pickerInput"
      no-title
      :max="maxValue"
      :min="minValue"
      :show-current="showCurrent"
      @input="menu = false"
      :active-picker="activePicker"
    ></v-date-picker>
  </v-menu>
</template>

<script>
import { formatDate } from "@/functions"
// В параметре date в родительском компоненте нужно использовать модификатор .sync
export default {
  name: "DatePicker",
  props: ['date', 'label', 'hint', 'min', 'max', 'showCurrent', 'placeholder', 'picker'],
  data () {
    return {
      menu: false,
      activePicker: null
    }
  },
  watch: {
    menu (val) {
      val && setTimeout(() => (this.activePicker = this.picker || 'DATE'))
    }
  },
  computed: {
    valueInput: {
      set (newValue) {
        this.$emit('update:date', newValue)
      },
      get: function() {
        return formatDate(this.date)
      }
    },
    pickerInput: {
      set (newValue) {
        this.$emit('update:date', newValue)
      },
      get: function() {
        return this.date
      }
    },
    minValue () {
      return this.min || null
    },
    maxValue () {
      return this.max || null
    }
  }
}
</script>

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question