vue3使用 setup 语法糖后如何在父组件用ref调用子组件的方法

什么是setup语法糖

  1. 更少的样板内容,更简洁的代码。
  2. 能够使用纯 Typescript 声明 props 和抛出事件。
  3. 更好的运行时性能 (其模板会被编译成与其同一作用域的渲染函数,没有任何的中间代理)。
//要使用这个语法,需要将 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
})

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐