Skip to content
文章目录

vue中如何获取插槽的dom对象

script setup 语法糖中

INFO

结论: 无法直接获取, 必须通过 render 方式对 slot 的 vnode 进行熏染,然后在 render 组件中的 mounted 方法中才能获取到。如下面的例子

初始版本

说明
通过手动render slot的vnode,从而拿到对应的dom,该例子中,对默认slot的dom节点,修改了颜色,添加了点击事件

改进版本

说明
改进版本的主要改进点在于那些对slot dom对象操作的方法与逻辑,不用再写在Render组件中,而可以一些在ChildSFC2中,方便进行职责分离

jsx/tsx 语法中

说明
这种方式如果不给slot原本对应的元素设置ref也是无法获取到对应dom的,说明这种方式有缺陷
说明
只有自行通过render函数渲染这种方式才是最稳妥的,即使slot原始的dom未设置ref,也能够获取到slot对应的dom

函数式组件

ts
// SlotRender.ts
// 使用: <SlotRender :vnode="oneVNode"></SlotRender>
import { h } from 'vue'

const SlotRender = (props, context) => {
  return props.vnode
}

SlotRender.props = ['vnode']

export default SlotRender
ts
// DynamicHeading.ts
import { h } from 'vue'

const DynamicHeading = (props, context) => {
  return h(`h${props.level}`, context.attrs, context.slots)
}

DynamicHeading.props = ['level']

export default DynamicHeading

函数式组件是一种定义自身没有任何状态的组件的方式。它们很像纯函数:接收 props,返回 vnodes。函数式组件在渲染过程中不会创建组件实例 (也就是说,没有 this),也不会触发常规的组件生命周期钩子。

我们用一个普通的函数而不是一个选项对象来创建函数式组件。该函数实际上就是该组件的渲染函数。

而因为函数式组件里没有 this 引用,Vue 会把 props 当作第一个参数传入:

第二个参数 context 包含三个属性:attrs、emit 和 slots。它们分别相当于组件实例的 $attrs、$emit 和 $slots 这几个属性。

大多数常规组件的配置选项在函数式组件中都不可用,除了 props 和 emits。我们可以给函数式组件添加对应的属性来声明它们:

js
MyComponent.props = ['value']
MyComponent.emits = ['click']

如果这个 props 选项没有被定义,那么被传入函数的 props 对象就会像 attrs 一样会包含所有 attribute。除非指定了 props 选项,否则每个 prop 的名字将不会基于驼峰命名法被一般化处理。

对于有明确 props 的函数式组件,attribute 透传的原理与普通组件基本相同。然而,对于没有明确指定 props 的函数式组件,只有 class、style 和 onXxx 事件监听器将默认从 attrs 中继承。在这两种情况下,可以将 inheritAttrs 设置为 false 来禁用属性继承:

js
MyComponent.inheritAttrs = false

相关问题

vue 如何便捷的判断 vnode 的类型?

【vue3 源码】十四、认识 vnode 中的 shapeFlag 和 patchFlag 属性

为什么补充了这个相关问题

是我尝试写智能布局组件时,尝试使用 tsx 语法实现,为什么会采用 tsx 语法,是因为 tsx 中可以获取到 slot 内容,并对 slot 中的每个元素进行修改,比如对 slot 元素再包一层元素。

重点来了:

第一:tsx 中获取到的 slot 内容,并非真实的 dom 节点,而是 vue 的 vnode,而暂时不太清楚是否有便捷的方式判断 vnode 类型

第二: slot 的 vnode 中居然还包含注释节点,这不是我期望的,而我又没找到简便可靠的方式判断 vnode 类型,所以也就没法排除这个注释节点,所以就影响了我的功能实现。

最终结论:

再没有找到确切的解决方案之前,还是不要使用 tsx 进行组件封装。未知内容太多了。

参考资料

Vue 中怎样获取具名 slot 的 DOM 节点