Bootstrap

Vue 3 中的标签 ref 与 defineExpose:模板引用与组件暴露

在 Vue 3 中,ref 不仅可以用于创建响应式数据,还可以用于获取 DOM 节点或组件实例。通过 ref,我们可以直接访问模板中的元素或组件,并在需要时操作它们。此外,defineExpose 用于在 <script setup> 语法中显式暴露组件的属性或方法。本文将详细介绍 refdefineExpose 的使用方法,并提供代码示例。


1. ref 的基本概念

ref 在模板中有两种主要用途:

  1. 获取 DOM 节点

    • ref 用在普通 DOM 标签上时,获取的是 DOM 节点。
  2. 获取组件实例

    • ref 用在组件标签上时,获取的是组件实例对象。

2. 使用 ref 获取 DOM 节点

我们可以通过 ref 获取模板中的 DOM 节点,并在脚本中操作它们。

2.1 代码示例

<template>
  <div class="person">
    <h2 ref="title2">前端</h2>
    <h3 ref="title3">Vue</h3>
    <input type="text" ref="input" placeholder="请输入内容" />
    <br /><br />
    <button @click="showLog">点我打印内容</button>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue';

// 获取 DOM 节点的引用
const title2 = ref<HTMLHeadingElement | null>(null);
const title3 = ref<HTMLHeadingElement | null>(null);
const input = ref<HTMLInputElement | null>(null);

// 打印 DOM 节点的内容
function showLog() {
  console.log('title2:', title2.value?.textContent);
  console.log('title3:', title3.value?.textContent);
  console.log('input value:', input.value?.value);
}
</script>

<style scoped>
.person {
  padding: 20px;
  background-color: #f0f0f0;
  border-radius: 10px;
  box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}

button {
  margin-top: 10px;
  padding: 5px 10px;
}
</style>

2.2 代码解析

  1. ref 获取 DOM 节点

    • 使用 ref 绑定到 h2h3input 标签上,获取它们的 DOM 节点。
    • 在脚本中通过 ref 的值访问这些 DOM 节点。
  2. 操作 DOM 节点

    • 点击按钮时,打印各个 DOM 节点的内容或值。

3. 使用 ref 获取组件实例

ref 用在组件标签上时,可以获取该组件的实例对象,从而访问组件的属性或方法。

3.1 代码示例

父组件(Parent.vue)
<template>
  <div>
    <Child ref="childRef" />
    <button @click="callChildMethod">调用子组件方法</button>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue';
import Child from './Child.vue';

// 获取子组件的实例
const childRef = ref<InstanceType<typeof Child> | null>(null);

// 调用子组件的方法
function callChildMethod() {
  childRef.value?.sayHello();
}
</script>
子组件(Child.vue)
<template>
  <div>
    <h1>子组件</h1>
  </div>
</template>

<script setup lang="ts">
// 暴露方法给父组件
function sayHello() {
  console.log('Hello from Child component!');
}

// 使用 defineExpose 暴露方法
defineExpose({
  sayHello
});
</script>

3.2 代码解析

  1. 父组件

    • 使用 ref 获取子组件的实例。
    • 通过 childRef.value 访问子组件暴露的方法 sayHello
  2. 子组件

    • 使用 defineExpose 显式暴露 sayHello 方法。
    • 父组件可以通过 ref 访问子组件的暴露内容。

4. defineExpose 的作用

<script setup> 语法中,组件的属性和方法默认是私有的,外部无法直接访问。通过 defineExpose,我们可以显式暴露组件的属性或方法,使父组件能够通过 ref 访问它们。

4.1 使用场景

  • 暴露组件的公共方法供父组件调用。
  • 暴露组件的内部状态或数据。

4.2 代码示例

<template>
  <div>
    <h1>子组件</h1>
    <p>计数:{{ count }}</p>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue';

const count = ref(0);

function increment() {
  count.value++;
}

// 暴露 count 和 increment
defineExpose({
  count,
  increment
});
</script>

5. 总结

  • ref 的作用

    • 获取 DOM 节点或组件实例。
    • 用于操作 DOM 或访问组件的属性和方法。
  • defineExpose 的作用

    • <script setup> 中显式暴露组件的属性或方法。
    • 使父组件能够通过 ref 访问子组件的暴露内容。
  • 适用场景

    • 操作 DOM 节点(如表单输入、动态样式等)。
    • 父子组件通信(如调用子组件方法、访问子组件状态)。

通过本文的介绍和代码示例,希望你能更好地理解 Vue 3 中 refdefineExpose 的使用方法,并在实际项目中灵活运用它们!

;