vue3 函数式组件获取不到内部方法

正在摸鱼中,领导突然来个问题:为啥通过defineComponent封装的组件获取不到子组件的方法呢?正在学习vue3知识的我大为感兴趣,就研究了一下。 

1、定义

图片

2、使用

选项语法

const Comp = defineComponent({
  setup(props) {
    // 就像在 <script setup> 中一样使用组合式 API
    const divEl = ref()
    onMounted(() => {
      console.log('7777', divEl.value)
    })
    return {
      divEl
    }
  },
  render() {
    return h('div', [
      h('div', {
        innerHTML: 'word1',
        onClick: () => {
          console.log('render>>>>>', this.divEl)
        }
      }),
      h(ElTree, { ref: 'divEl' })
    ])
  }
})

函数语法

const Comp = defineComponent(
  (props, { expose }) => {
    // 就像在 <script setup> 中一样使用组合式 API
    const divEl = ref()
    onMounted(() => {
      console.log('7777', divEl.value)
    })
    return () =>
      h('div', [
        h('div', {
          innerHTML: 'word1',
          onClick: () => {
            console.log(divEl)
          }
        }),
        h(ElTree, { ref: divEl })
      ])
  },
  // 其他选项,例如声明 props 和 emits。
  {
    props: {
      /* ... */
    }
  }
)

3、问题

使用选项语法时,可以在父组件正常获取ElTree的方法。但是使用函数语法时获取的却是dom元素

图片

查看defineComponent发现两者没有什么区别,函数语法判断第一个参数是否是函数,如果是函数,则将setup属性继承到组件配置中。最终返回的参数是一样的。

function defineComponent(options, extraOptions) {
  return shared.isFunction(options) ? (
   (() => 
   shared.extend({ name: options.name }, 
                   extraOptions, 
                   { setup: options })
   )()
  ) : options;
}

4、解决

直到在官方文档中看到setup与渲染函数一起使用的案例

图片

这个就和上面的函数语法一样,setup返回的是一个渲染函数。而这样会造成一定的问题。

图片

最终官方提供expose()解决问题

const Comp = defineComponent(
  (props, { expose }) => {
    // 就像在 <script setup> 中一样使用组合式 API
    const divEl = ref()
    onMounted(() => {
      console.log('7777', divEl.value)
    })
    expose({
      divEl
    })
    return () =>
      h('div', [
        h('div', {
          innerHTML: 'word1',
          onClick: () => {
            console.log(divEl)
          }
        }),
        h(ElTree, { ref: divEl })
      ])
  },
  // 其他选项,例如声明 props 和 emits。
  {
    props: {
      /* ... */
    }
  }
)

图片

 可以关注我的公众号,交流相关技术,谢谢支持!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值