1

I'm trying to design a component that select a date range in VueJS. From a specific key ("realtime", "today", "yesterday") that the component get via a props, or changed by the user using a selector, it will returns:

  • start/stop date as a JS Date object
  • start/stop human representation of the period
  • human representation of the key according to the locale.

My conceptual goal is to use a such component like this (invalid syntax, but it is just to explain the issue):

Select your period:
<DateRangeSelector v-model="drskey" ref="drs">

Selected period: {{ drs.periodName }}
Dates: {{ drs.dateStartHuman }} to {{ drs.dateStopHuman }}

Please note that:

  • no VueX state (there is no need to store anything here in a global state)
  • i don't want to store anything else than the "key" in the "parent" component
  • refs doesn't work because they are not initialized at the beginning

Any advices?

tito
  • 12,990
  • 1
  • 55
  • 75

1 Answers1

0

If you don't want to store anything else than the "key" in the parent component, then why not to move the output of the generated strings into the child component itself.. Then you could watch the changes of the props or of the select input and output the strings without ever going back to the parent…

However if your use case example is not complete and you need to do more stuff with the data in the parent, then another approach would be for the v-model to use an object instead of a string. Something like {key: 'realtime'}. Then inside the child component, when the value changes, you could emit the 'input' event with the 'filled-up' object where you add all the calculated data.. So in the parent you would use the data exactly as you have shown in your example.. Something like this:

Parent Component:

    Select your period:
    <data-range-selector v-model="drs" />
    Selected period: {{ drs.periodName }}
    Dates: {{ drs.dateStartHuman }} to {{ drs.dateStopHuman }}
    {    
      data: () => ({ 
        drs: {key: 'realtime'} 
      })
    }

Child Component:

<input v-model="key">
    {
      props: { value: Object },
      data: () => ({ key: '' }),
      watch: {
        value () { this.key = this.value.key },
        key () { this.returnResults()   }
      },
      created () {
          this.key = this.value.key
          this.returnResults()
      },
        computed: {
        periodName () { return this.key },
        dateStartHuman () { return `When ${this.key} starts` },
        dateStopHuman () { return `When ${this.key} stops` }
      },

      methods: {
        returnResults () {
          this.$emit('input', {
            key: this.key,
            periodName: this.periodName, 
            dateStartHuman: this.dateStartHuman,
            dateStopHuman: this.dateStopHuman
          })
        }
      }
    }

Here is the working fiddle.. https://jsfiddle.net/tyminko/jwLet0n5/13/

maxim
  • 616
  • 4
  • 7