Vue3 ref获取元素节点

前言

虽然在 Vue 中不提倡我们直接操作 DOM,毕竟 Vue 的理念是以数据驱动视图。但是在实际情况中,我们有很多需求都是需要直接操作 DOM 节点的,这个时候 Vue 提供了一种方式让我们可以获取 DOM 节点:ref 属性。ref 属性是 Vue2 和 Vue3 中都有的,但是使用方式却不大一样,这也导致了很多从 Vue2 转到 Vue3 的小伙伴感到有些困惑。

Vue3 中 ref 访问元素

Vue3 中通过 ref 访问元素节点与 Vue2 不太一样,在 Vue3 中我们是没有 this 的,所以当然也没有 this.$refs。想要获取 ref,我们只能通过声明变量的方式。

<template>
	<view>
		<button ref="hello" id="10">
			这里是组件
		</button>
	</view>
</template>

<script setup>
	import { onMounted, ref } from 'vue';
	const hello = ref(null)
	onMounted(()=>{
		console.log(hello.value) //通过.value可以查看target中的值
		console.log(hello.value.id) //获取属性值
		console.log(hello.value.$el.innerHTML) //获取内容值
	})
<think>我们正在使用Vue 3和TypeScript,需要获取DOM元素的高度。根据引用[3],有几种方式可以获取DOM元素。但是,引用[3]提到的方式(使用getCurrentInstance)并不推荐,因为它比较麻烦且类型不安全。 在Vue 3中,推荐使用`ref`来获取DOM元素。我们可以通过以下步骤实现: 1. 在模板中,给需要获取高度的元素添加一个ref属性,例如:`ref="myElement"` 2. 在组件的`setup`函数或`<script setup>`中,使用`ref`函数创建一个同名的ref对象,初始值为`null`(注意:在TypeScript中,我们需要指定类型为`HTMLElement | null`) 3. 在生命周期钩子(如`onMounted`)或需要的时候访问这个ref对象,通过其`value`属性获取DOM元素,然后使用`clientHeight`或`offsetHeight`等属性获取高度。 下面是一个示例代码: ```vue <template> <div ref="myElement">需要获取高度的元素</div> </template> <script lang="ts"> import { defineComponent, ref, onMounted } from &#39;vue&#39; export default defineComponent({ setup() { // 创建一个ref来存储元素,类型为HTMLElement或null const myElement = ref<HTMLElement | null>(null) onMounted(() => { // 在挂载后,myElement.value就是DOM元素 if (myElement.value) { const height = myElement.value.clientHeight console.log(&#39;元素高度:&#39;, height) } }) return { myElement // 必须返回,模板才能关联 } } }) </script> ``` 或者,如果你使用`<script setup>`语法糖(更简洁): ```vue <template> <div ref="myElement">需要获取高度的元素</div> </template> <script setup lang="ts"> import { ref, onMounted } from &#39;vue&#39; const myElement = ref<HTMLElement | null>(null) onMounted(() => { if (myElement.value) { const height = myElement.value.clientHeight console.log(&#39;元素高度:&#39;, height) } }) </script> ``` 注意: - 我们使用`ref`函数创建了一个响应式引用`myElement`,并指定了它的类型为`HTMLElement | null`(因为初始值为null,当元素挂载后,它会被赋值为实际的DOM元素)。 - 在`onMounted`生命周期钩子中,我们确保元素已经挂载,然后通过`myElement.value`访问DOM元素。 - 使用`clientHeight`获取元素的高度(包括内边距,但不包括边框、外边距和滚动条)。如果需要包括边框和外边距等,可以使用`offsetHeight`,具体根据需求选择。 另外,引用[3]还提到了其他方式,但使用`ref`是最直接和推荐的方式。 **相关问题:** 1.Vue 3中,如何监听元素高度的变化? 2. 除了`clientHeight`和`offsetHeight`,还有哪些属性可以获取元素尺寸? 3.Vue 3的Composition API中,如何获取多个DOM元素?</think>在 Vue 3 中使用 TypeScript 获取 DOM 元素高度,推荐使用 Composition API 的 `ref` 方式。以下是具体实现方法: ### 推荐方式:使用模板引用(Template Ref) ```vue <template> <div ref="targetElement">需要测量高度的元素</div> </template> <script setup lang="ts"> import { ref, onMounted } from &#39;vue&#39; // 1. 创建与模板同名的 ref(类型为 HTMLElement | null) const targetElement = ref<HTMLElement | null>(null) // 2. 在组件挂载后获取高度 onMounted(() => { if (targetElement.value) { const height = targetElement.value.clientHeight // 获取可见高度 // 或使用 offsetHeight(包含边框)或 scrollHeight(包含溢出内容) console.log("元素高度:", height) } }) </script> ``` ### 备选方式:使用 getCurrentInstance(不推荐) ```vue <script setup lang="ts"> import { getCurrentInstance, onMounted } from &#39;vue&#39; onMounted(() => { const instance = getCurrentInstance() if (instance) { const el = instance.refs.myElement as HTMLElement console.log("高度:", el.clientHeight) } }) </script> <template> <div ref="myElement">目标元素</div> </template> ``` ### 关键说明: 1. **类型声明**:使用 `ref<HTMLElement | null>(null)` 确保 TypeScript 类型安全 2. **生命周期**:必须在 `onMounted` 或之后获取,确保 DOM 已渲染 3. **高度属性**: - `clientHeight`:可见内容高度(含内边距) - `offsetHeight`:包含边框和滚动条 - `scrollHeight`:包含溢出内容的高度 4. **响应式更新**:如需动态监听高度变化,可结合 `ResizeObserver` ### 最佳实践建议: ```typescript // 封装为可复用函数 import { Ref } from &#39;vue&#39; export function useElementHeight(elRef: Ref<HTMLElement | null>) { const height = ref(0) onMounted(() => { watchEffect(() => { if (elRef.value) { height.value = elRef.value.clientHeight } }) }) return { height } } // 组件内使用 const { height } = useElementHeight(targetElement) ``` > ⚠️ 注意:避免在 `setup` 中直接操作 DOM,应通过生命周期钩子访问 --- ### 相关问题 1. Vue 3 中如何监听 DOM 元素尺寸变化? 2. TypeScript 如何为自定义 DOM 操作定义类型? 3. Composition API 和 Options API 获取 DOM 有何区别? 4. 如何获取动态生成的组件内部元素高度? 5. Vue 3 中使用 `ResizeObserver` 的最佳实践是什么? [^1]: Vue3 TypeScript 集成指南 [^2]: Composition API 最佳实践 [^3]: Vue3 DOM 操作官方文档
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

黑石课堂

请给我打钱!!!谢谢,不客气!

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

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

打赏作者

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

抵扣说明:

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

余额充值