当前位置: 首页 > 知识库问答 >
问题:

vue3 - Vue 3中如何正确获取子组件插槽内的DOM实例?

时仰岳
2024-06-27

vue3中,怎么获取子组件插槽内的DOM实例或者说ref?

我尝试这样获取,但是获取不到:

//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聚焦,不考虑自定指令    //发现子组件的setSlotRef没有执行</script>

共有2个答案

陈夜洛
2024-06-27

你这样也太依赖插槽的内容组件了吧。
给子组件添加一个 autofocusprops 属性,让插槽元素内部自己去处理自动聚焦不行吗?

伯英武
2024-06-27

在 Vue 3 中,插槽的内容实际上并不直接由子组件管理,而是由父组件插入到子组件的模板中。因此,你无法在子组件中直接访问插槽内容的 DOM 实例。但是,你可以通过一些方法间接地实现这个需求。

在你的例子中,base-popup 组件尝试将一个 ref 函数传递给插槽,但是 <slot> 元素不支持直接绑定 ref 函数。<slot> 的内容是由父组件控制的,并且 ref 函数必须在父组件的上下文中被调用。

下面是一个如何在 Vue 3 中获取插槽内容 DOM 实例的示例:

base-popup.vue

<template>  <div class="base-popup">    <!-- 不需要在这里绑定 ref 到 slot,因为插槽内容不由 base-popup 控制 -->    <slot name="default" :message="slotMessage"></slot>  </div></template><script setup>import { ref, defineProps } from 'vue';const slotMessage = ref('base-popup slot message');// 你可以在这里定义其他 props 或逻辑,但无法直接访问插槽 DOM</script>

ds-popup.vue

<template>  <base-popup ref="popup">    <template #default="{ message }">      <input ref="slotInput" type="text" :value="message" @mounted="focusInput" />    </template>  </base-popup></template><script setup>import { ref, onMounted } from 'vue';const popup = ref(null); // 这里只是获取 base-popup 的引用,但无法直接访问插槽内容const slotInput = ref(null); // 这里的 ref 绑定到 input 元素上// 在 input 挂载后使其聚焦function focusInput() {  slotInput.value.focus();}onMounted(focusInput); // 在组件挂载后调用 focusInput 函数</script>

在上面的 ds-popup.vue 示例中,我们直接在父组件的 <template> 中为插槽内容(即 <input> 元素)绑定了一个 ref。然后,在 onMounted 生命周期钩子中调用了 focusInput 函数,该函数使 <input> 元素获得焦点。

请注意,ref 是定义在父组件的 ds-popup.vue 中,并且直接绑定到插槽内容(即 <input> 元素)上。这是因为插槽内容实际上是由父组件渲染的,所以只有父组件可以访问并操作这些内容的 DOM 实例。

 类似资料:
  • 在调用这个组件的地方 接收childer组件作为插槽,在parent中 获取不到默认插槽的属性b,不知道为什么

  • 如何在Children内部拿到父级的ref? 父级是不同的组件

  • 为什么我不可以通过ref获取盒子的dom(vue3)

  • 主要内容:全局组件实例,实例,实例,全局组件实例,局部组件实例,Prop,Prop 实例,Prop 实例组件(Component)是 Vue.js 最强大的功能之一。 组件可以扩展 HTML 元素,封装可重用的代码。 组件系统让我们可以用独立可复用的小组件来构建大型应用,几乎任意类型的应用的界面都可以抽象为一个组件树: 每个 Vue 应用都是通过用 createApp 函数创建的,传递给 createApp 的选项用于配置根组件。当我们挂载应用时,该组件被用作渲染的起点。 一个应用需要被挂载到一

  • 父组件 子组件 为什么执行getSonData的时候,无法获取到子组件的data?sonRef.value.data只能在onMounted内使用吗?不能在父组件的方法里执行?

  • 许多类型的组件,例如标签、菜单、照片库等等,需要内容去渲染。 就像浏览器内建的 <select> 需要 <option> 子项,我们的 <custom-tabs> 可能需要实际的标签内容来起作用。并且一个 <custom-menu> 可能需要菜单子项。 使用了 <custom-menu> 的代码如下所示: <custom-menu> <title>Candy menu</title> <i

  • vue3中子组件向父组件传值 在传值的时候为什么只能在声明一个方法的时候传递,而不能在定义click的时候传递呢

  • 想要写一个Popover,计算元素位置使用的是floating-ui,需要获取触发元素的Ref和Popover内容的Ref来进行定位。 触发元素和内容通过插槽传入,遇到的问题是如何获取插槽内元素的Ref Popover 伪代码: 使用: 目前我能想到的办法就是在触发元素和内容外套一层div,然后用div的Ref 但是这样就多了一层节点,在想能不能有更好的解决方案?