defineExpose 、defineProps、defineEmits --- vue3组件间通讯1

 defineExpose 、defineProps、defineEmits 是vue3的写法并且是一个仅 <script setup> 中可用的编译宏命令,并不需要显式地导入;

defineExpose 来显式指定在 <script setup> 组件中要暴露出去的属性。

defineProps、defineEmits在vue3的非语法糖setup和在vue2中的写法是 props,emit 

defineExpose   子传父 

(用在子组件,暴露想传递的值或方法,父组件通过ref属性获取子组件暴露的)

1. 作用

defineExpose定义:用于组件通信中父级组件调用操作子组建方法和响应式属性参数能力,即子组件将值和方法传给父组件。

2. 原理

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

那么,通过 defineExpose 编译器宏来显式指定在 <script setup> 组件中要暴露出去的属性

然后,父组件通过ref属性访问子组件

3. 实例

 父组件:

<Index ref="childeRef"></Index>

<script setup>
    import Index from "./index.vue";

    const childeRef = ref();

    function test() {
        console.log(childeRef.value.msg) // Hello World
    }

    onMounted(() => {
      let flag:boolean = true;
      let value:number= 5;
      childeRef.value.childFn(flag,value) // 调用子组件函数, 输出 6
    })

</script>

子组件:

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

    function childFn(type:boolean, data:number) {
        console.log('我是子组件');
        if(data){
           let value = data + 1;   
           return value;
        }
    }
    
    const msg = 'Hello World';
    const num = ref(0);
    
    defineExpose({ //暴露想要传递的值或方法
        msg,
        childFn,
    });
</script>

defineProps  父传子 

(用在子组件,接收父组件的传值,用来声明props)

1. 作用

它可以帮助我们在组件中自定义 props,并定义它们的数据类型和默认值。使用这个新特性,可以更加方便地管理组件的 Props 数据

2. 原理

defineProps() 宏中的参数不可以访问 <script setup>中定义的其他变量,因为在编译时整个表达式都会被移到外部的函数中,即必须在<script setup>的顶层使用,不可以在<script setup>的局部变量中引用;

3. 实例

父组件:

<templte>
   <sub-task-detail
      v-model:open="subTaskDetailVisible"
      :task-info="task"
      :sub-task-id="subTaskId"
      :tab="tabIndex"
    />
</templte>

<script setup>
    
    const subTaskDetailVisible = ref(false)
    
    const handleDetail = (row) => {
      subTaskDetailVisible.value = true
      subTaskId.value = row.id
      tabIndex.value = 1
    }

</script>

子组件:

<script setup>
import { ref, watch, onMounted, onBeforeUnmount, h } from 'vue'
import { subTaskDetail, downloadLog } from '@/api/detail'
import BigDataList from './BigDataList.vue'
import dayjs from 'dayjs'
import { useI18n } from 'vue-i18n'
import { MIGRATION_MODE, SUB_TASK_STATUS } from '@/utils/constants'

const { t } = useI18n()

const props = defineProps({
  open: Boolean,
  taskInfo: Object,
  subTaskId: [String, Number],
  tab: [String, Number]
})
//也可以let props = defineProps(['open','taskInfo','subTaskId','tab']);

onMounted(() => {
  visible.value = props.open
})

</script>

defineEmits  子传父 

(用在子组件,将子组件的方法传递给父组件,用来声明emits)
 

1. 作用

用于在setup中注册自定义事件,方便开发者监听和绑定事件。是一个宏函数,使用时无需导入

2. 原理

不可以访问 <script setup>中定义的其他变量,因为在编译时整个表达式都会被移到外部的函数中,即defineEmits必须放在全局,否则报错。

3. 实例

父组件:

<template>

 <add-jdbc ref="addJdbcRef" @finish="finishAddJdbc" />
 
</template>

<script setup>
import { reactive, ref, computed, watch, onMounted, toRaw, h, compile } from 'vue'
import AddJdbc from '../components/AddJdbc.vue'
import { sourceClusters, targetClusters, sourceClusterDbsData, targetClusterDbsData } from '@/api/task'
 
const finishAddJdbc = (type) => {
  if (type === 'ORACLE'||type === 'MYSQL') {
    getSourceClustersData()
  } else {
    getTargetClustersData()
  }
}
</script>

子组件:

<script setup>
//defineEmits接受一个数组,元素为自定义事件名
//返回一个触发器,用于触发事件,第一个参数是具体事件名,第二个是传递的值

 emits = defineEmits([`finish`])

 const submit = () => {
    // save
    data.loading = true

    const param = {
      clusterName: data.form.name,
      dbType: data.form.dbType,
      deployType: data.form.nodes.length > 1 ? 'CLUSTER' : 'SINGLE_NODE',
      nodes: []
    }

    addJdbc(param).then((res) => {
      data.loading = false
      if (Number(res.code) === 200) {
        Message.success({ content: `Create success` })
        emits(`finish`, data.form.dbType)
      }
      close()
    })
}

  • 9
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值