在 Vue 3 中,ref
不仅可以用于创建响应式数据,还可以用于获取 DOM 节点或组件实例。通过 ref
,我们可以直接访问模板中的元素或组件,并在需要时操作它们。此外,defineExpose
用于在 <script setup>
语法中显式暴露组件的属性或方法。本文将详细介绍 ref
和 defineExpose
的使用方法,并提供代码示例。
1. ref
的基本概念
ref
在模板中有两种主要用途:
-
获取 DOM 节点:
- 当
ref
用在普通 DOM 标签上时,获取的是 DOM 节点。
- 当
-
获取组件实例:
- 当
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 代码解析
-
ref
获取 DOM 节点:- 使用
ref
绑定到h2
、h3
和input
标签上,获取它们的 DOM 节点。 - 在脚本中通过
ref
的值访问这些 DOM 节点。
- 使用
-
操作 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 代码解析
-
父组件:
- 使用
ref
获取子组件的实例。 - 通过
childRef.value
访问子组件暴露的方法sayHello
。
- 使用
-
子组件:
- 使用
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 中 ref
和 defineExpose
的使用方法,并在实际项目中灵活运用它们!