Vue3 defineExpose要在方法声明定义以后使用的教程
feixianxing 人气:0defineExpose要在变量和方法声明定义之后再使用,否则浏览器的控制台会输出很多警告,并且最终将该页面卡死。
[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("Nicholas.") const sayName = ()=>{ console.log("my name is "+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) // "Nicholas" child.value.sayName() // "my name is Nicholas" }) </script>
总结
向外暴露的时候变量会自动解包,比如上面子组件的name:ref<String>
暴露到父组件的时候自动变成了name:String
.
注:defineExpose一定要在变量和方法声明定义之后再使用。
不知道以后会不会有修改,不过在2023/02/17
,如果defineExpose
写在变量和函数前面,那么浏览器的控制台会输出很多警告,并且最终将该页面卡死。
扩展:vue3 defineExpose
vue3使用 setup 语法糖后如何在父组件用ref调用子组件的方法
什么是setup语法糖
- 更少的样板内容,更简洁的代码。
- 能够使用纯 Typescript 声明 props 和抛出事件。
- 更好的运行时性能 (其模板会被编译成与其同一作用域的渲染函数,没有任何的中间代理)。
//要使用这个语法,需要将 setup attribute 添加到 <script> 代码块上: <script setup> console.log('hello script setup') //里面的代码会被编译成组件 setup() 函数的内容。这意味着与普通的 <script> 只在组件被首次引入的时候执行一次不同,<script setup> 中的代码会在每次组件实例被创建的时候执行。 </script>
当我们的组件使用这种语法时,是不可以用setup()这种语法的写法获取子组件的数据或方法
为了在 script setup 组件中明确要暴露出去的属性,使用 defineExpose 编译器宏:
<script setup> import { ref } from 'vue' const a = 1 const b = ref(2) defineExpose({ a, b }) //当父组件通过模板 ref 的方式获取到当前组件的实例,获取到的实例会像这样 { a: number, b: number } (ref 会和在普通实例中一样被自动解包) </script>
下面是vue3 使用setup()后 父组件获取子组件的方法
1、父组件
template中
<Table ref="eleTable" @handle="handleFun"></Table> import { ref } from 'vue'
2、子组件
setup() { //ref方法 const eleTable = ref() //eleTable是页面ref后面对应的名字 const clickSon = () => { eleTable.value.changeShowText() //调用子组件的方法 let arr = eleTable.value.tableData //获取子组件 setup 里面定义的变量 } }
使用语法糖之后的写法
父组件
<FastreplySettingTable ref="FastreplySettingTableRef" v-if="sysStore.msgList" :groupType="Math.abs(state.currentTab - 1)" :currentTab="state.currentTab" ></FastreplySettingTable> <script> const FastreplySettingTableRef = ref(); //该方法是一个点击事件 function sendEvent(action) { if (FastreplySettingTableRef) { //拿到FastreplySettingTableRef组件里的dispatchEvent方法 并且穿一些参数 FastreplySettingTableRef.value.dispatchEvent({ action, groupType: Math.abs(state.currentTab - 1) }) } } </script>
子组件
import { getCurrentInstance, onMounted, reactive, onBeforeUnmount, defineProps, defineEmits, computed, onBeforeMount, onUnmounted, watch, ref, //这里必须引入 defineExpose } from "vue"; // 希望被父组件调用到的方法 //这个方法必须写在defineExpose 上面才会生效 const dispatchEvent = ({ action, groupType }) => { switch (action) { case 'tabClick': { state.searchKeyword = '', state.activeGroup = 'all' }; break; case 'addfastMsg': { //上报 openMask('addfastMsg'); // state.DialogTitle = state.groupType ? "快捷消息管理-添加团队内容" : "快捷消息管理-添加个人内容" // spiderReport.paq(props.groupType ? "快捷消息管理-添加团队内容" : "快捷消息管理-添加个人内容"); }; break; default: { // state.[action](groupType); } } } defineExpose({ dispatchEvent })
加载全部内容