Vue3获取Dom元素与子组件

在Vue3中,获取DOM元素或组件节点的方式略有变化,仍然使用ref但需配合ref的实例类型。通过`ref<HTMLElement>`定义DOM元素节点,用`ref<InstanceType<typeofChild>>`定义组件节点,以获得更好的类型提示和代码补全。在`onMounted`生命周期钩子中安全地访问这些引用,同时处理可能的null值以避免严格模式下的类型检查错误。
摘要由CSDN通过智能技术生成

在Vue2时我们想获取DOM元素或者组件节点时一般使用this.$refs.xxx。现在在Vue3时代,需要稍微改变一点点方法 ,但是还依然使用ref来获取。

<template>
  <!-- 一个dom元素节点 -->
  <div ref="domRef">这是一个DOM元素</div>
  <!-- 一个子组件 -->
  <child ref="childRef"></child>
</template>

下面是实现逻辑:

import { defineComponent, onMounted, ref } from 'vue'
import Child from '@components/child.vue'
export default defineComponent({
  components: {
    Child
  },
  setup() {
    // 定义元素的节点类型
    const domRef = ref<HTMLElement>()
    // 定义组件的节点类型,使用 InstanceType 配合 typeof 获取子组件的类型
    const childRef = ref<InstanceType<typeof Child>>()
    // 获取元素或者组件时,需要在视图渲染完毕之后进行
    onMounted(() => {
      const text = domRef.value.innerText;
      // 操作子组件
      if (childRef.value) {
        childRef.value.visible = true;
      }
    })
    // 使用ref声明的变量必须return出去才能被template正常使用
    return {
      domRef,
      childRef
    }
  }
})

单纯使用 typeof Child 虽然可以获得 Child.vue 组件的 Props 和方法等提示,但在 VSCode 的类型推导还不够智能,缺乏更有效的代码补全支持。

上文使用的 InstanceType<T>TypeScript 提供的一个工具类型,可以获取构造函数类型的实例类型,因此将组件的类型声明为 InstanceType<typeof Child> ,不仅可以得到更完善的类型提示,在编程过程中还可以让编辑器提供更完善的代码补全功能。

上面代码还有一个细节是对childRef.value增加了一个是否为空的判断,这主要是为了解决TS报错的问题。这是因为一些脚手架创建出来的项目会默认启用 --strictNullChecks 选项,导致可能存在null和undefined类型,所以为了解决这个问题才有了上述方案,不过还有另一种方案是

// 如果仅仅是读取值,则可以使用可选?操作符
const value = childRef.value?.visible;
// 如果是赋值操作,则需要先判断是否为空
if (childRef.value) {
  childRef.value.visible = true;
}
Vue中,组件获取DOM元素的方法有几种。一种是通过在组件的模板中使用`:ref`指令来给DOM元素添加一个引用,然后在父组件中可以通过`$refs`来访问这个引用。例如,可以在组件的模板中使用`:ref`指令来给一个div元素添加引用: ``` <template> <div ref="myDiv">这是一个div元素</div> </template> ``` 然后在父组件中,可以通过`this.$refs`来访问这个引用: ``` mounted() { console.log(this.$refs.myDiv); } ``` 另一种方法是通过在组件的`mounted`钩函数中使用`this.$el`来获取组件的根DOM元素。例如: ``` mounted() { console.log(this.$el); } ``` 这样就可以获取组件的根DOM元素了。注意,这种方法只能在组件的`mounted`钩函数中使用,因为只有在组件挂载到DOM树上之后,才能获取DOM元素。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [Vue.js实例学习:获取DOM元素](https://blog.csdn.net/b954960630/article/details/87739962)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* [Vue3中操作dom的四种方式,建议收藏!!!](https://blog.csdn.net/qq_44880095/article/details/128721041)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

绝对零度HCL

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值