when use component template ref then get null in vue3 render function

57 views Asked by At

I attempted to refactor Vue SFC (Single File Component) code into Vue render (h), functions, but encountered an issue with using component template references in the children property of the render function. If I extract the variable, I cannot access the reference value, but if I put it into the children, I can access it.

here is my two code sippnets:

this is unexpected:

import { h, defineComponent, reactive, ref, onMounted, defineExpose } from 'vue'
import { type PropType, type VNode } from 'vue'
import { Form, FormItem, Input, Button } from 'ant-design-vue'

export default defineComponent({
  // ...
  setup: (props: any, { expose }) => {
    const formRef = ref()

    onMounted(() => {
      console.log(formRef.value) // null
    })
    const form = h(
      Form,
      { ref: formRef, labelCol: formLabelCol, wrapperCol: formWrapperCol, model },
      formItems
    )
    return () =>
      h(
        'div',
        {
          style: {
            width: props.width ? props.width + 'px' : 'auto'
          }
        },
        [formTitle, form]
      )
  }
})

this is ok:

import { h, defineComponent, reactive, ref, onMounted, defineExpose } from 'vue'
import { type PropType, type VNode } from 'vue'
import { Form, FormItem, Input, Button } from 'ant-design-vue'

export default defineComponent({
  // ...
  setup: (props: any, { expose }) => {
    const formRef = ref()

    onMounted(() => {
      console.log(formRef.value) // got form ref function
    })
    return () =>
      h(
        'div',
        {
          style: {
            width: props.width ? props.width + 'px' : 'auto'
          }
        },
        [
          formTitle, 
          h(Form,
          { ref: formRef, labelCol: formLabelCol, wrapperCol: formWrapperCol, model },
          formItems)
        ]
      )
  }
})
1

There are 1 answers

1
eminoda On

cost a day, I got how to fix:

import { h, defineComponent, reactive, ref, onMounted, defineExpose } from 'vue'
import { type PropType, type VNode } from 'vue'
import { Form, FormItem, Input, Button } from 'ant-design-vue'

export default defineComponent({
  // ...
  setup: (props: any, { expose }) => {
    const formRef = ref()

    onMounted(() => {
      console.log(formRef.value) // null
    })
   
    return () =>{
      // put into render function
      const form = h(
         Form,
         { ref: formRef, labelCol: formLabelCol, wrapperCol: formWrapperCol, model },
      formItems
    )
      return h(
        'div',
        {
          style: {
            width: props.width ? props.width + 'px' : 'auto'
          }
        },
        [formTitle, form]
      )
  }}
})