基于本文回答

播面 播面

文图音视,全方位拆解八股文
0
评论

Vue 中如何获取 DOM?

知识点图片

在 Vue 中获取 DOM 元素,最推荐且最常用的方法是使用 ref 属性

虽然 Vue 是声明式的(数据驱动视图),但在某些场景下(如集成第三方库、管理焦点、Canvas 绘图等),我们确实需要直接操作 DOM。

以下是针对 Vue 3Vue 2 的具体实现方式:


1. Vue 3 (<script setup> 组合式 API)

在 Vue 3 中,获取 DOM 需要声明一个与模板中 ref 属性同名的响应式变量。

步骤:

  1. 在模板元素上添加 ref="xxx"
  2. 在脚本中创建一个同名的 ref 变量,初始值为 null
  3. onMounted 生命周期钩子中访问(必须等待组件挂载完成,DOM 才存在)。
plaintext
<template>
  <!-- 1. 绑定 ref 名称 -->
  <input type="text" ref="myInput" />
  <button @click="focusInput">聚焦</button>
</template>

<script setup>
import { ref, onMounted } from 'vue'

// 2. 声明同名变量,初始值为 null
const myInput = ref(null)

// 3. 在生命周期钩子中访问
onMounted(() => {
  // 注意:DOM 元素在 .value 中
  console.log(myInput.value) 
  myInput.value.focus()
})

const focusInput = () => {
  // 在事件处理中也可以访问
  myInput.value.focus()
}
</script>

2. Vue 2 (选项式 API)

在 Vue 2 中,所有的 ref 都会被注册到 this.$refs 对象上。

步骤:

  1. 在模板元素上添加 ref="xxx"
  2. mounted 钩子或方法中通过 this.$refs.xxx 访问。
plaintext
<template>
  <div>
    <div ref="myBox">这是一个盒子</div>
  </div>
</template>

<script>
export default {
  mounted() {
    // 访问 DOM
    const element = this.$refs.myBox
    console.log(element)
    element.style.color = 'red'
  }
}
</script>

3. 特殊情况与注意事项

A. 在 v-for 循环中使用 ref

  • Vue 2: this.$refs.xxx 会自动变成一个数组,包含循环出来的所有元素。
  • Vue 3: 需要绑定一个函数来收集元素,或者使用数组类型的 ref。
plaintext
<!-- Vue 3 v-for 获取 DOM 示例 -->
<template>
  <ul>
    <li v-for="item in list" :key="item" :ref="(el) => setItemRef(el)">
      {{ item }}
    </li>
  </ul>
</template>

<script setup>
import { ref, onMounted } from 'vue'

const list = [1, 2, 3]
const itemRefs = ref([])

// 将元素推入数组
const setItemRef = (el) => {
  if (el) {
    itemRefs.value.push(el)
  }
}

onMounted(() => {
  console.log(itemRefs.value) // 包含所有 li 元素的数组
})
</script>

B. 获取组件实例 vs 获取 DOM

如果 ref 绑定的是一个子组件(而不是原生 HTML 标签):

  • Vue 2: this.$refs.child 获取的是子组件实例(可以使用 this.$refs.child.$el 获取该组件的根 DOM)。
  • Vue 3: myRef.value 获取的是子组件实例。如果想获取该组件内部的 DOM,通常需要子组件通过 defineExpose 暴露特定的 DOM,或者直接访问 $el(不推荐直接依赖 $el,建议组件间通信)。

C. 为什么不能在 created 中获取?

created 阶段,Vue 实例已经初始化,但 DOM 还没有被渲染和挂载。必须在 mounted 生命周期之后才能获取到真实的 DOM 元素。

总结

方式 语法 关键点
Vue 3 const el = ref(null) 访问时用 el.value,变量名必须与模板 ref 一致
Vue 2 this.$refs.el 直接通过 $refs 对象访问
原生 JS document.querySelector 不推荐。破坏了 Vue 的封装性,且容易产生时序问题
00:00
00:00