@alenov
Программист

Как установить activePicker в кастомном компоненте на основе v-date-picker?

Делаю кастомный компонент для v-date-picker. В идеале: передавать параметр activePicker, чтобы выбирать, какой picker использовать по умолчанию. Например, для выбора даты рождения использовать YEAR. Но в данный момент не могу вообще заставить работать параметр activePicker.

Вот код компонента:

<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>


Запускаю так:

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


В консоли:
[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"


В чём засада? Я ведь даже пока не передаю параметр, который позволит установить activePicker.
  • Вопрос задан
  • 107 просмотров
Пригласить эксперта
Ответы на вопрос 1
@alenov Автор вопроса
Программист
Сделал так, работает:

<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>
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы