vue3中插槽传到组件内部的,怎么才能获取到ref

问题描述

我尝试做一个popover组件,大致参考element ui 使用插槽做,但是发现插槽传过去的没法获取到ref。

相关代码

调用
image.png
组件里:
image.png

组件data:
image.png

尝试的方法

拿不到... slots返回的是一个虚拟节点 尝试手动挂载无果...
image.png

...提问三十分钟后自行曲线救国解决了 但仍想知道答案。

阅读 14.9k
7 个回答

父组件的ref只能通过父组件获取,父组件获取自己的实例传到子组件
父组件
import {getCurrentInstance} from 'vue'
let instance=getCurrentInstance()
<child :ins="instance">
<input ref="input"/>
</child>
子组件
setup(prop,ctx){
prop.ins.refs.ins//这就是slot传过来的input的ref
}

试一下

console.log(this.$slots)

如果多个插槽

// 排序空格其他内容
this.slotChildren = []
for (let i = 0; i< this.$slots.default.length; i++) {
  if (that.$slots.default[i].elm.nodeType !== 3) {
    that.slotChildren.push(that.$slots.default[i]) // 获得那些插入的内容
  }
}
新手上路,请多包涵

vue3中,我也遇到这样的封装组件问题,想知道最后你的解决方案是哪一个!

新手上路,请多包涵

我也有遇到这种场景, 是用<component :is="$slots.default()[0]"></component>这样实现的,但是要用作用域插槽就gg了...

通过Vue3的函数模板引用可以解决此问题

图片.png

具体实现:

  1. 组件内定义引用和设置引用的方法:
//定义引用
let formRef: Ref<typeof ElForm | undefined> = ref()
//设置引用的方法
function setFormRef(el: any){
  console.log('拿到表单引用', el)
  formRef.value = el
}
  1. 定义插槽
    <slot :form="setFormRef" :model="innerModel"/>
  2. 插入插槽
<yi-action
  text="打招呼"
  icon="el-icon-bell"
  type="default"
  :api="{
    url: '/demo/sayhi',
    method: 'post',
    data: {
      word: 'hello'
    }
  }"
  modal-title="标题"
>
  <template #default="{ form, model }">
    <el-form :ref="form" :model="model">
      <el-form-item prop="name" required label="姓名">
        <el-input v-model="model.name" />
      </el-form-item>
    </el-form>
  </template>
</yi-action>

这样,插入插槽处的el-form挂载时,调用绑定到ref的函数,最终,组件内部的formRef.value获取到表单的引用

源码来自yimi-element-plus

@至尊幽蓝
setFormRef方法没有执行。
按照你思路,我写了一下我的组件,发现setSlotRef方法没有执行,message能正常获取到。

//base-popup.vue 孙子组件
<template>
    <slot :defaultSlotRef="setSlotRef" message="base-popup slot message" />
</template>
<script setup>
    import {
        ref
    } from 'vue';
    
    let slotRef = ref()
    function setSlotRef(el) {
        slotRef.value = el
        console.log('1:我执行了', el)
    }
</script>

//ds-popup.vue 孩子组件
<template>
    <base-popup ref="popup">
        <template #default="{defaultSlotRef,message}">
            <input :ref="defaultSlotRef" type="text" :value="message" />
        </template>
    </base-popup>
</template>
<script setup>
    //我想默认让这个input聚焦,不考虑自定指令
</script>

可以在slot外层添加一个 div,在这个div 添加reference属性解决

 <div class="inline-block" ref="reference">
     <slot></slot>
 </div>
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题