0
votes

Is there a way to bind (and expose in the component itself) "data"/"methods" using the Composition API in using a "render" function (and not a template) in Vue.js?

(Previously, in the Options API, if you use a render method in the options configuration, all of the data/props/methods are still exposed in the component itself, and can be still accessed by componentInstance.someDataOrSomeMethod)

Templated Component:

<template>
  <div @click="increment">{{ counter }}</div>
</template>
<script lang="ts">
import { defineComponent, Ref, ref, computed } from '@vue/composition-api'
export default defineComponent({
  name: 'TranslationSidebar',
  setup () {
    const counter: Ref<number> = ref(0)
    const increment = () => {
      counter.value++
    }
    return {
      counter: computed(() => counter.value),
      increment
    } // THIS PROPERTY AND METHOD WILL BE EXPOSED IN THE COMPONENT ITSELF
  }
})
</script>

Inspected Component of Templated Composition API Component

Non-Templated "Render" Component:

<script lang="ts">
import { defineComponent, Ref, ref, createElement } from '@vue/composition-api'
export default defineComponent({
  name: 'TranslationSidebar',
  setup () {
    const counter: Ref<number> = ref(0)
    const increment = () => {
      counter.value++
    }
    return () => {
      return createElement('div', { on: { click: increment } }, String(counter.value))
    } // THE COUNTER PROP AND INCREMENT ARE BOUND, BUT NOT EXPOSED IN THE COMPONENT ITSELF
  }
})
</script>

Inspected Component of Non-Templated Composition API Component

Options API using the render option:

<script lang="ts">
export default {
  name: 'Test',
  data () {
    return {
      counter: 0
    }
  },
  mounted () {
    console.log('this', this)
  },
  methods: {
    increment () {
      this.counter++
    }
  },
  render (h) {
    return h('div', { on: { click: this.increment } }, this.counter)
  }
}
</script>

Inspected Options API Component w/render

1

1 Answers

0
votes

I can't make any claim that this is the proper way as it seems pretty hacky and not really ideal, but it does do what I need to do for now. This solution uses the provide method which grants access to properties/methods provided via componentInstance._provided. Not really ecstatic doing it this way though:

<script lang="ts">
import { defineComponent, Ref, ref, createElement, provide, computed } from '@vue/composition-api'
export default defineComponent({
  name: 'TranslationSidebar',
  setup () {
    const counter: Ref<number> = ref(0)
    const increment = () => {
      counter.value++
    }
    provide('increment', increment)
    provide('counter', computed(() => counter.value))
    return () => {
      return createElement('div', { on: { click: increment } }, String(counter.value))
    }
  }
})
</script>

enter image description here