vue3 | defineExpose的使用

发布时间 2023-09-21 15:05:15作者: 杨芋可可

简介

使用<script setup>的组件是默认关闭的————即通过模板引用或者$parent链获取到的组件的公开实例,不会暴露在任何在<script setup>中声明的绑定

换句话说,如果一个子组件使用的是选项式 API 或没有使用 <script setup>,被引用的组件实例和该子组件的 this 完全一致,这意味着父组件对子组件的每一个属性和方法都有完全的访问权。

但是如果使用了 <script setup> 的组件,这种组件是默认私有的,也就是一个父组件无法访问到一个使用了 <script setup> 的子组件中的任何东西,除非子组件在其中通过 defineExpose 宏显式暴露:

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

const a = 1
const b = ref(2)

// 像 defineExpose 这样的编译器宏不需要导入
defineExpose({
  a,
  b
})
</script>

举个栗子

父组件获取子组件的实例,去触发子组件实例身上的方法。

defineExpose-demo.gif

父组件

<template>
<div class="p-20 pb-0 mb-4">
  <div>父组件</div>
  <button class="mt-4" @click="handleClick">点我聚焦</button>
</div>
<Child ref="childeRef"></Child>
</template>
  
<script setup lang="ts">
import { ref, provide, onMounted } from "vue";
import Child from "./Child.vue";

const childeRef = ref<HTMLInputElement | null>(null);

const handleClick = () => {
  childeRef.value?.inputRef?.focus();
};
</script>

子组件

<template>
  <hr />
  <div class="p-20 pt-4">
    <div>子组件</div>
    <input
      ref="inputRef"
      placeholder="请输入哈哈哈哈"
      class="border-1 mt-4"
    /><br />
  </div>
</template>

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

const inputRef = ref<HTMLInputElement | null>(null);

defineExpose({
  inputRef,
});
</script>

参考文档: