Inheritance & Composition with Vue Components

Kyle Coberly

kylecoberly.com

Kyle Coberly

  • Educator
  • Business Dork
  • Software Developer

Objectives

  • Describe inheritance in Vue
  • Describe composition in Vue

Calendar Time Blocks

Inheritance

  • `extends`
  • Children take precedence
  • All hooks fire
  • Use for "Is-A" relationships
// TimeBlockEvent
import TimeBlock from './TimeBlock'

export default {
  extends: TimeBlock,
  props: {
    block: Object,
  },
  computed: {
    blockStyles() {
      // Specific Styles
    },
  },
}
// TimeBlock
export default {
  props: {
    maximumDuration: Number,
    minimumDuration: {
      type: Number,
      default: 0.5,
    },
  },
  computed: {
    blockClasses() {
      // Default styles
    },
  },
}

Inheritance

  • Wrap shared content in the component
  • Careful about passing props and events
// TimeBlockEvent
<template>
  <TimeBlock
    theme="event"
    :style="blockStyles"
  >
    <TimeBlockLabel
      :startTime="block.startTime"
      :duration="block.duration"
    />
  </TimeBlock>
</template>
// TimeBlock
<template>
  <div
    class="timeblock"
    :class="blockClasses"
  >
    <slot />
  </div>
</template>

Composition

  • `mixins`
  • Mixin takes precedence
  • All hooks fire
  • Use for "Has-A" relationships
  • Use a component for shared content
// TimeBlockEvent
import TimeBlock from './TimeBlock'

import dragAndDroppable from '../mixins/drag-drop-block'
import stretchUppable from '../mixins/stretch-up-block'
import stretchDownable from '../mixins/stretch-down-block'

export default {
  extends: TimeBlock,
  mixins: [
    dragAndDroppable,
    stretchUppable,
    stretchDownable,
  ],
}
// drag-drop-block.js
export default {
  data() {
    return {
      isMoving: false,
    }
  },
  methods: {
    startMove(event) { },
    move(event) { },
    doneMoving() { },
  },
}

Why?

  •  DRY Code
  • Consuming code looks 😍 
<div class="local--day--blocks local--day--event-blocks">
  <TimeBlockEvent
    v-for="(event, index) in events"
    :block="event"
    @updatePosition="updateBlockPosition('event', index)"
    @click.native.stop="selectEvent(event, index)"
  />
</div>

Why Not?

  • "Where the fuck is this happening??"
  • Template inheritance is awkward

Thank You!

kylecoberly.com

Inheritance & Composition with Vue Components

By Kyle Coberly

Inheritance & Composition with Vue Components

  • 1,454