1

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.

lfmunoz
  • 822
  • 1
  • 9
  • 16
  • @tao Edit: removed the return . That isn't the issue. – lfmunoz Feb 20 '23 at 00:38
  • Consider creating a *runnable* [mcve]. Use codesandbox.io or similar if needed. – tao Feb 20 '23 at 00:51
  • why aren't you usign a `SIngle File Component`? I think it's an easier way than yours, without using `render function` – Álvaro Feb 20 '23 at 08:36
  • @Álvaro doing something way more complicated (i.e, creating forms dynamically) this is just part that isn't working. – lfmunoz Feb 20 '23 at 18:50

2 Answers2

1

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

Tolbxela
  • 4,767
  • 3
  • 21
  • 42
0

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>
Tolbxela
  • 4,767
  • 3
  • 21
  • 42