[Vue3] defineExpose用法

17,159 阅读1分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 2 天,点击查看活动详情

一、问题

在Vue3中,父组件可通过创建一个ref(null),然后将赋值的元素写在当前子组件上即可,在需要的时候,通过定义的响应式变量即可获取,获取后即可取得当前子组件内部dom以及当前子组件内部变量方法等,并且直接使用子组件内部方法。但是有时候获取的时候返回的没有什么信息只有一个{_v_skin:true}这个信息,这条信息表示数据无法响应。

二、原因及方法

原因: 使用 <script setup> 语法糖的组件是默认关闭的,也即通过模板 ref 或者 $parent 链获取到的组件的公开实例,不会暴露任何在 <script setup>中声明的绑定。
方法: 为了在 <script setup> 语法糖组件中明确要暴露出去的属性,使用 defineExpose 编译器宏将需要暴露出去的变量与方法放入暴露出去就可以.

三、[Vue3] defineExpose要在方法声明定义以后使用

Vue3中的setup默认是封闭的,如果要从子组件向父组件暴露属性和方法,需要用到defineExpose。 和defineProps、defineEmits一样,这三个函数都是内置的,不需要import,不过defineProps,defineEmits都会返回一个实例,而defineExpose是没有返回值的。

const props = defineProps({}) 
const emit = defineEmits([]) 
defineExpose({})

四、defineExpose的使用

子组件Child.vue

<template>
    {{ name }}
</template>
<script setup>
import { ref } from 'vue'
const name = ref("张三")
const sayName = ()=>{
    console.log("我叫 "+name.value)
}
defineExpose({
    name,
    sayName
});
</script>

父组件Father.vue

<template>
    <Child ref="child"></Child>
</template>
<script setup>
import { ref, onMounted } from 'vue'
const child = ref(null)
onMounted(()=>{
    console.log(child.value.name)	// "张三"
    child.value.sayName()		// "我叫张三"
})
</script>

结束语

1、向外暴露的时候变量会自动解包,比如上面子组件的name:ref<String>暴露到父组件的时候自动变成了name:String. 2、注:defineExpose一定要在变量和方法声明定义之后再使用。 不知道以后会不会有修改,不过在2023/02/22,如果defineExpose写在变量和函数前面,那么浏览器的控制台会输出很多警告,并且最终将该页面卡死。