This " /> This " /> This "/>

VueJs 3 - Reactive Render Function using Script Setup and Composition API

1.1k Views Asked by At

I have a component called x-input that works as following:

     <x-input k="name" v-model="r"></x-input>
     <x-input k="name" :modelValue="r"></x-input>

This works fine and it is reactive.

How do I create the same functionality using a render function with Composition API and <script setup>?

Here is what i am trying but doesn't work:

<script setup>
import { h, ref} from 'vue'
const r = ref("test")
const entity =  h(resolveComponent('x-input'), {k: "name",   modelValue: r  }, {})
</script>

<template>
<entity />
</template>

Here entity is not reactive.

2

There are 2 best solutions below

0
Tolbxela On BEST ANSWER

Where do you define/import your x-input component?

If you import it, then you don't need to resolve it.

<script setup>
import { h, ref, resolveComponent, } from 'vue'
import xInput from './xInput.vue'
const k = ref("name")
const r = ref("test")
const update = () => {
          k.value = "name new"
          r.value = "test new"
      }

const entity = h('div',
      [ h('p', 'Entity: '),
        h(xInput, {k: k,   modelValue: r  }),
        h('button',  { onClick: () => { update() } }, 'update')
      ])  
</script>

<template>
  <entity />
</template>

Here is the working SFC Playground

0
Tolbxela On

You don't need to resolve your component. Just use the component itself.

h(xInput, {k: k,   modelValue: r  }, {}), 

resolveComponent() is great when you have dynamic component names.
Check: https://stackoverflow.com/a/75405334/2487565

Here is the working playground

const { createApp, h, ref, resolveComponent  } = Vue;

const xInput = {
  name: 'x-input',
  props: ['k', 'modelValue'],
  template: '<div>k: {{k}}<br/>modelValue: {{modelValue}}<br/></div>' 
}

const Entity = {
  components: {
    xInput
  },
  setup(props, { attrs, slots, emit, expose } ) {
      const r = ref("test")
      const k = ref("name")
      const update = () => {
          k.value = "name new"
          r.value = "test new"
      }
      return () => h('div', 
        [ 
          // You don't need to resolve your component
          h(xInput, {k: k,   modelValue: r  }, {}), 
          h(resolveComponent('x-input'), {k: k,   modelValue: r  }, {}),
          h('button',  { onClick: () => { update() } }, 'update')
        ])
   }
}
const app = createApp({ components: { Entity } })
app.mount('#app')
#app { line-height: 1.5; }
[v-cloak] { display: none; }
<div id="app">  
  <entity></entity>
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>