vue3的setup 语法糖中获取slot 插槽的dom对象

最近使用vue3开发项目,需要封装一个无限滚动的组件,使用scroll组件内置插槽接受模板的方式,所以需要在scroll组件内获取到模板渲染后dom元素的宽高。
但是setup语法糖是组件生命周期的beforeCreate和created中,而且经过测试,在mounted函数中的el属性也是null,所以得出结论模板的slot.default无法直接获取, 必须通过 render 方式对 slot 的 vnode 进行渲染,然后在 render 组件中的 mounted 方法中才能获取到。如下面的例子

容器组件 ScrollView

//ScrollView.vue  scroll容器组件
<script setup lang="ts">
 import { ref, useSlots } from 'vue'
 import createSlot from '../vnode/createSlot'
 const slot = useSlots()
 // 这里获取到的是默认插槽的vnode,但拿不到对应的dom实例
 const defaultSlot = slots.default && slots.default()[0]

 // 自定义template 内容mounted事件
 const mountedCallFun = (args)=> {
  console.log('mounted', args)
 }
 // 自定义template 内容updated事件
 const updatedCallFun = (args)=> {
  console.log(args)
 }
 // 自定义template 内容unMounted卸载事件
 const unmountedCallFun = (args)=> {
  console.log(args)
 }
 const mySlot = createSlot({mountedCallFun, updatedCallFun, unmountedCallFun})
 onMounted(() => {
  // 即使在该组件的mounted钩子中,这个defaultSlot的$el依然为null
  console.log('defaultSlot', defaultSlot)
 })
</script>

<template>
  <div>
    <mySlot :vnode="defaultSlot"></mySlot>
  </div>
</template>

render函数渲染slot内容的工厂函数 createSlots.ts

通过 vue官方提供的 defineComponent创建一个组件装载 scrollView组件中的 插槽内容:

//createSlots.ts
import { defineComponent, h } from "vue"
type CallFun = (vnodeEl: HTMLElement) => void
type Funs = Record<'mountedCallFun'| 'updatedCallFun'| 'unmountedCallFun', CallFun>
export default ({mountedCallFun, updatedCallFun, unmountedCallFun}: Funs) => {
  return defineComponent({
    props: ['vnode'],
    setup(props, ctx){
      console.log(props, ctx)
    },
    mounted() {
      // console.log(this.$el)
      mountedCallFun(this.$el)
    },
    render(props: any, ctx: any) {
      console.log(props, ctx)
      return props.vnode
    }
  })
}

测试使用 ScrollView组件

<script setup lang="ts">
  import Text from '../components/text.vue'
  import ScrollView from '../components/ScrollView.vue'
</script>

<template>
  <div>
    <ScrollView>
      <h2 >测试使用 ScrollView组件测试使用 ScrollView组件</h2>
      <h2 >测试使用 ScrollView组件测试使用 ScrollView组件</h2>
      <h2 >测试使用 ScrollView组件测试使用 ScrollView组件</h2>
      <h2 >测试使用 ScrollView组件测试使用 ScrollView组件</h2>
    </ScrollView>
  </div>
</template>
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
Vue通过使用`$slots`属性来获取插槽slot)的DOM内容。 在Vue,支持使用命名插槽和默认插槽。命名插槽允许我们在组件定义多个插槽,并使用不同的名称进行区分。默认插槽则是没有具体名称的插槽。 要获取插槽DOM,我们可以使用`$slots`属性。`$slots`属性是一个对象,包含了所有插槽内容。每个插槽都可以通过其名称来访问。 例如,假设我们在父组件使用了一个带有默认插槽和命名插槽的子组件,我们可以通过以下方式获取它们的DOM内容: ```html <template> <child-component> <p slot="header">This is the header slot.</p> <p>This is the default slot.</p> </child-component> </template> ``` ```javascript // 子组件 <template> <div> <slot name="header"></slot> <slot></slot> </div> </template> <script> export default { mounted() { const headerSlotContent = this.$slots.header; // 获取命名插槽DOM const defaultSlotContent = this.$slots.default; // 获取默认插槽DOM console.log(headerSlotContent); console.log(defaultSlotContent); }, } </script> ``` 在子组件的`mounted`生命周期钩子,我们可以通过`this.$slots`来获取插槽DOM内容。`$slots`是一个包含了插槽名称作为键,对应DOM内容对象。我们可以通过插槽的名称来访问相应的DOM。 当上述代码执行时,控制台会输出命名插槽和默认插槽DOM内容。我们可以根据需要对插槽DOM进行操作或渲染。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值