如果一个子组件应用的是选项式 API 或没有应用 <script setup>,被援用的组件实例和该子组件的 this 完全一致,这意味着父组件对子组件的每一个属性和办法都有齐全的拜访权。这使得在父组件和子组件之间创立严密耦合的实现细节变得很容易,当然也因而,应该只在相对须要时才应用组件援用。大多数状况下,你应该首先应用规范的 props 和 emit 接口来实现父子组件交互。

有一个例外的状况,应用了 <script setup> 的组件是默认公有的:一个父组件无法访问到一个应用了 <script setup> 的子组件中的任何货色,除非子组件在其中通过 defineExpose 宏显式裸露

<script setup>import { ref } from 'vue'const a = 1const b = ref(2)// 像 defineExpose 这样的编译器宏不须要导入defineExpose({  a,  b})</script>

当父组件通过模板援用获取到了该组件的实例时,失去的实例类型为 { a: number, b: number } (ref 都会主动解包,和个别的实例一样)。

为组件模板援用标注类型

有时,你可能须要为一个子组件增加一个模板援用,以便调用它公开的办法。举例来说,咱们有一个 MyModal 子组件,它有一个关上模态框的办法:

<!-- MyModal.vue --><script setup lang="ts">import { ref } from 'vue'const isContentShown = ref(false)const open = () => (isContentShown.value = true)defineExpose({  open})</script>

为了获取 MyModal 的类型,咱们首先须要通过 typeof 失去其类型,再应用 TypeScript 内置的 InstanceType 工具类型来获取其实例类型:

<!-- App.vue --><script setup lang="ts">import MyModal from './MyModal.vue'const modal = ref<InstanceType<typeof MyModal> | null>(null)const openModal = () => {  modal.value?.open()}</script>

留神,如果你想在 TypeScript 文件而不是在 Vue SFC 中应用这种技巧,须要开启 Volar 的 Takeover 模式。

本文由博客一文多发平台 OpenWrite 公布!