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

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 实例。

 类似资料: