vue3通过ref可以拿到DOM原理

1,092 阅读2分钟

在 Vue 3 中,通过 ref 可以获取到 DOM 元素,这在 Vue 2 中也是类似的,不过 Vue 3 引入了 Composition API,使得使用 ref 变得更加灵活和强大。以下是详细的原理和源码讲解。

基本用法

在 Vue 3 中,ref 可以用来引用 DOM 元素或组件实例。以下是一个简单的示例:

<template>
  <div ref="myDiv">Hello, Vue 3!</div>
</template>

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

export default {
  setup() {
    const myDiv = ref(null);

    onMounted(() => {
      console.log(myDiv.value); // 这里可以访问到 DOM 元素
    });

    return {
      myDiv
    };
  }
};
</script>

原理分析

1. ref 函数

ref 函数来自 Vue 的 Composition API,用于创建一个响应式的引用。它返回一个包含 .value 属性的对象,这个属性可以被用来存储任意值,包括 DOM 元素。

import { ref } from 'vue';

const myDiv = ref(null); // 创建一个 ref 对象

2. onMounted 钩子

onMounted 是一个生命周期钩子,它在组件挂载完成后执行。在这个钩子中,我们可以安全地访问 DOM 元素,因为此时 DOM 已经被渲染。

onMounted(() => {
  console.log(myDiv.value); // 访问 DOM 元素
});

3. 模板中的 ref 属性

在模板中使用 ref 属性时,Vue 会自动将对应的 DOM 元素赋值给 ref 对象的 .value 属性。

<div ref="myDiv">Hello, Vue 3!</div>

源码分析

以下是 Vue 3 中 refonMounted 的简化实现原理。

ref 的实现

ref 的实现非常简单,核心是返回一个包含 .value 属性的对象,并且这个对象是响应式的。

import { reactive } from 'vue';

function ref(initialValue) {
  return reactive({ value: initialValue });
}

onMounted 的实现

onMounted 的实现涉及到 Vue 的生命周期管理。它将传入的回调函数存储在一个内部的队列中,当组件挂载完成后,依次执行这些回调。

function onMounted(callback) {
  // 假设我们有一个全局的当前组件实例
  const currentInstance = getCurrentInstance();

  if (currentInstance) {
    currentInstance.mounted.push(callback);
  }
}

模板编译

在模板编译阶段,Vue 会将 ref 属性编译成一个指令,在组件挂载时执行该指令,将 DOM 元素赋值给对应的 ref 对象。

function setRef(refObject, domElement) {
  refObject.value = domElement;
}

通过 refonMounted,Vue 3 提供了一种简洁且强大的方式来访问 DOM 元素。ref 函数创建了一个响应式引用,而 onMounted 确保在生命周期的正确阶段访问 DOM。模板中的 ref 属性则通过编译阶段的处理,将 DOM 元素与 ref 对象关联起来。