Will Vue 3 bring the end of renderless components

October 2020 - Stéphane Reiss

Who am I?

  • Web developer
  • Backend background
  • I love javascript

Stéphane Reiss

Agenda

  1. Vue Montreal
  2. What is a renderless component
  3. The composition API
  4. Workshop - Calendar event management
    Migrating to the composition API
  5. Closing remarks

Vue Montreal

Community started 2 years ago

900+ members

 

Everyone is welcome to join our slack to discuss Vue, get programming help or just say hi!

Vue Montreal

This presentation is a continuation this one: Renderless Components

What is a renderless component

Components that don’t render anything

<script>
export default {
  render() {
    return this.$scopedSlots.default();
  }
};
</script>

Renderless components relies on Scoped Slots

<template>
  <RenderlessComponent>
    <div>whatever</div>
  </RenderlessComponent>
</template>

default slot

slots

<template>
  <RenderlessComponent v-slot="slotProps">
    <div>whatever + {{ slotProps }}</div>
  </RenderlessComponent>
</template>

default slot with scope from RenderlessComponent

scoped slots

Why renderless component

How to update the look of a component while keeping its functionalities, without sacrificing maintainability?

Solution: renderless components

Why renderless component - Tags input

<script>
export default {
  props: ['value'],
  data() {
    return {
      newTag: '',
    }
  },
  methods: {
    addTag() {
      if (this.newTag.trim().length === 0 || this.value.includes(this.newTag.trim())) {
        return
      }
      this.$emit('input', [...this.value, this.newTag.trim()])
      this.newTag = ''
    },
    removeTag(tag) {
      this.$emit('input', this.value.filter(t => t !== tag))
    }
  },
  render() {
    return this.$scopedSlots.default({
      tags: this.value,
      addTag: this.addTag,
      removeTag: this.removeTag,
      inputAttrs: {
        value: this.newTag,
      },
      inputEvents: {
        input: (e) => { this.newTag = e.target.value },
        keydown: (e) => {
          if (e.keyCode === 13) {
            e.preventDefault()
            this.addTag()
          }
        }
      }
    })
  },
})
</script>

renderless-tags-input.vue

<script>
import { reactive, computed } from 'vue'

export default {
  setup() {
    const state = reactive({
      count: 0,
      double: computed(() => state.count * 2)
    })

    function increment() {
      state.count++
    }

    return {
      state,
      increment
    }
  }
}
</script>

<template>
  <button @click="increment">
    Count is: {{ state.count }}, double is: {{ state.double }}
  </button>
</template>

Calendar events

Source code can be found here:
https://github.com/T0RAT0RA/renderless-components

Let's code!

Will Vue 3 bring the end of renderless components?

Eventually, yes.

Thank you!

Will Vue 3 bring the end of renderless components

By Stéphane Reiss

Will Vue 3 bring the end of renderless components

  • 555