Home > Software engineering >  What do the method arguments mean when creating a calendar in Vuetify?
What do the method arguments mean when creating a calendar in Vuetify?

Time:02-04

What I want to solves

I am creating a calendar with Vuetify. There is something I don't understand in the Vuetify code. I'm trying to understand it by looking at the sample code on the official site, but it looks like the Vuetify methods are passed unique arguments in the script methods, I've also checked the API, are the arguments to get the time and other events derived from Vuetify?

Code

template

<template>
  <v-row >
    <v-col>
      <v-sheet height="600">
        <v-calendar
          ref="calendar"
          v-model="value"
          color="primary"
          type="4day"
          :events="events"
          :event-color="getEventColor"
          :event-ripple="false"
          @change="getEvents"
          @mousedown:event="startDrag"
          @mousedown:time="startTime"
          @mousemove:time="mouseMove"
          @mouseup:time="endDrag"
          @mouseleave.native="cancelDrag"
        >
          <template v-slot:event="{ event, timed, eventSummary }">
            <div
              
              v-html="eventSummary()"
            ></div>
            <div
              v-if="timed"
              
              @mousedown.stop="extendBottom(event)"
            ></div>
          </template>
        </v-calendar>
      </v-sheet>
    </v-col>
  </v-row>
</template>

script

<script>
  export default {
    data: () => ({
      value: '',
      events: [],
      colors: ['#2196F3', '#3F51B5', '#673AB7', '#00BCD4', '#4CAF50', '#FF9800', '#757575'],
      names: ['Meeting', 'Holiday', 'PTO', 'Travel', 'Event', 'Birthday', 'Conference', 'Party'],
      dragEvent: null,
      dragStart: null,
      createEvent: null,
      createStart: null,
      extendOriginal: null,
    }),
    methods: {
      startDrag ({ event, timed }) {
        if (event && timed) {
          this.dragEvent = event
          this.dragTime = null
          this.extendOriginal = null
        }
      },
      startTime (tms) {
        const mouse = this.toTime(tms)

        if (this.dragEvent && this.dragTime === null) {
          const start = this.dragEvent.start

          this.dragTime = mouse - start
        } else {
          this.createStart = this.roundTime(mouse)
          this.createEvent = {
            name: `Event #${this.events.length}`,
            color: this.rndElement(this.colors),
            start: this.createStart,
            end: this.createStart,
            timed: true,
          }

          this.events.push(this.createEvent)
        }
      },
      extendBottom (event) {
        this.createEvent = event
        this.createStart = event.start
        this.extendOriginal = event.end
      },
      mouseMove (tms) {
        const mouse = this.toTime(tms)

        if (this.dragEvent && this.dragTime !== null) {
          const start = this.dragEvent.start
          const end = this.dragEvent.end
          const duration = end - start
          const newStartTime = mouse - this.dragTime
          const newStart = this.roundTime(newStartTime)
          const newEnd = newStart   duration

          this.dragEvent.start = newStart
          this.dragEvent.end = newEnd
        } else if (this.createEvent && this.createStart !== null) {
          const mouseRounded = this.roundTime(mouse, false)
          const min = Math.min(mouseRounded, this.createStart)
          const max = Math.max(mouseRounded, this.createStart)

          this.createEvent.start = min
          this.createEvent.end = max
        }
      },
      endDrag () {
        this.dragTime = null
        this.dragEvent = null
        this.createEvent = null
        this.createStart = null
        this.extendOriginal = null
      },
      cancelDrag () {
        if (this.createEvent) {
          if (this.extendOriginal) {
            this.createEvent.end = this.extendOriginal
          } else {
            const i = this.events.indexOf(this.createEvent)
            if (i !== -1) {
              this.events.splice(i, 1)
            }
          }
        }

        this.createEvent = null
        this.createStart = null
        this.dragTime = null
        this.dragEvent = null
      },
      roundTime (time, down = true) {
        const roundTo = 15 // minutes
        const roundDownTime = roundTo * 60 * 1000

        return down
          ? time - time % roundDownTime
          : time   (roundDownTime - (time % roundDownTime))
      },
      toTime (tms) {
        return new Date(tms.year, tms.month - 1, tms.day, tms.hour, tms.minute).getTime()
      },
      getEventColor (event) {
        const rgb = parseInt(event.color.substring(1), 16)
        const r = (rgb >> 16) & 0xFF
        const g = (rgb >> 8) & 0xFF
        const b = (rgb >> 0) & 0xFF

        return event === this.dragEvent
          ? `rgba(${r}, ${g}, ${b}, 0.7)`
          : event === this.createEvent
            ? `rgba(${r}, ${g}, ${b}, 0.7)`
            : event.color
      },
      getEvents ({ start, end }) {
        const events = []

        const min = new Date(`${start.date}T00:00:00`).getTime()
        const max = new Date(`${end.date}T23:59:59`).getTime()
        const days = (max - min) / 86400000
        const eventCount = this.rnd(days, days   20)

        for (let i = 0; i < eventCount; i  ) {
          const timed = this.rnd(0, 3) !== 0
          const firstTimestamp = this.rnd(min, max)
          const secondTimestamp = this.rnd(2, timed ? 8 : 288) * 900000
          const start = firstTimestamp - (firstTimestamp % 900000)
          const end = start   secondTimestamp

          events.push({
            name: this.rndElement(this.names),
            color: this.rndElement(this.colors),
            start,
            end,
            timed,
          })
        }

        this.events = events
      },
      rnd (a, b) {
        return Math.floor((b - a   1) * Math.random())   a
      },
      rndElement (arr) {
        return arr[this.rnd(0, arr.length - 1)]
      },
    },
  }
</script>

For example, startDrag in the method takes event and timed as arguments. Also, in the click section that I am referring to while looking at the sample, it is showEvent ({ nativeEvent, event }), and I think the arguments for nativeEvent and event are also wrong. There was also another method called updateRange ({ start, end }). Furthermore, it also takes the arguments (tms) and (event), but there are no values passed in the template, so I wonder why it is working. The following is the official website of Vuetify. https://vuetifyjs.com/en/components/calendars/#click

CodePudding user response:

Event handling in Vue

When the value of the v-on directive (@ for shorthand) is a function name, the template compiler converts it into a function call that includes the event argument.

For example, this markup:

<CustomButton @submit="upload">Submit</CustomButton>

...is equivalent to:

<CustomButton @submit="(e) => upload(e)">Submit</CustomButton>

The event argument (e) is the data the CustomButton passed when emitting the submit event. Assume CustomButton's doSomething() is called here:

// CustomButton.vue
export default {
  methods: {
    doSomething() {
      const eventData = { name: 'product 1', quantity: 100 }
      this.$emit('submit', eventData) 
    }
  }
}

Notice the type of event argument is:

{
  name: string,
  quantity: number,
}

Given the @submit handling setup above, the parent would recieve the submit event, and call upload() with that event argument:

// Parent.vue
export default {
  methods: {
    upload(eventData) {
      console.log({ name: eventData.name, quantity: eventData.quantity })
    }
  }
}

With object destructuring in the argument list, that code can be rewritten as this:

// Parent.vue
export default {
  methods: {
    upload({ name, quantity }) {
      console.log({ name, quantity })
    }
  }
}

And that's the pattern you're seeing in the sample code.

Events

The Vuetify API docs for each component list all events and their arguments (v-calendar's API / events).

Given the event arguments below, it makes sense to see the following method signatures...

@mousedown:event="startDrag"

Event argument for mousedown:event:

{
  event: any,
  ⋮
  timed: boolean,
  ⋮
}

Method signature:

export default {
  methods: {
    startDrag({ event, timed }) {⋯}
  }
}

@click:event="showEvent"

Event argument for click:event:

{
  event: any,
  ⋮
  nativeEvent: MouseEvent | TouchEvent
}

Method signature:

export default {
  methods: {
    showEvent({ event, nativeEvent }) {⋯}
  }
}

@change="updateRange"

Event argument for change:

{
  start: {⋯},
  end: {⋯}
}

Method signature:

export default {
  methods: {
    updateRange({ start, end }) {⋯}
  }
}
  •  Tags:  
  • Related