vue3父子组件相互调用方法详解,可使用defineEmits 和defineProps

1、前言

vue3项目开发中,我们常常会遇到父子组件相互调用的场景,下面以setup语法糖格式详细聊聊父子组件那些事儿。

2、父组件调用子组件方法

2.1 子组件Child.vue

<template>
	<div>我是子组件</div>
</template>
 
<script setup>
// 第一步:定义子组件的方法
const sayHello = (value) => {
	console.log(value)
}
// 第二部:暴露方法
defineExpose({
	sayHello 
})
</script>

2.2 父组件Father.vue

<template>
	<button @click="getChild">触发子组件方法</button>
	<child ref="childRef" />
</template>
<script setup>
import Child from './components/child.vue'
// 定义与 ref 同名变量
const childRef = ref(null)
const getChild = () => {
	// 调用子组件的方法或者变量,通过value
	childRef.value.hello("hello world!");//这个方法没测试,应该是sayHello()?
}
</script>

3、子组件调用父组件方法

3.1 父组件Father.vue

<template>
	<child @sayHello="handle" />
</template>
 
<script setup>
	import Child from './components/child.vue';
	const handle = () => {
		console.log('子组件调用了父组件的方法')
	}
</script>

3.2 子组件Child.vue

<template>
	<view>我是子组件</view>
	<button @click="sayHello">调用父组件的方法</button>
</template>
 
<script setup>
	const emit = defineEmits(["sayHello"])
	const sayHello = () => {
		emit('Hello World')
	}
</script>

vue3 defineEmits的使用

简介:用于父子组件通信时,子组件向父组件传递数据,不需要被导入即可使用,会在编译 <script setup>语法块时一同编译。注意的是 defineEmits 只能在 <script setup>的顶层使用

使用
1、定义子组件

// 子组件 child.vue
 
<template>
  <button @click="handelClick">传递给父级</button>
  <button @click="add">加</button>
  <button @click="decrease">减</button>
</template>
 
<script setup lang="ts">

const emits = defineEmits(['clickFn', 'add', 'decrease'])// 定义一个或多个自定义事件

const handelClick = () => {
  emits('clickFn', { name: '张三', age: 18,id: 1 }) // 第一个参数为自定义事件名  第二个参数为要传递的数据
  //上面这么写,传入的参数是一个map对象,接收的时候使用.name,.age,.id
  //也可以这么做,不使用对象来传递参数,而是直接传递多个参数,这样接收的时候,按照顺序接收参数
  //父组件的函数不使用对象接收,而是使用(name,age,id)来接收参数
   emits('clickFn', '张三', 18,1);
}
const add = () => {
  emits('add', 10) // 第一个参数为自定义事件名  第二个参数为要传递的数据
}
const decrease = () => {
  emits('decrease', 3) // 第一个参数为自定义事件名  第二个参数为要传递的数据
}

 
</script>

2、定义父组件

// 父组件 parent.vue
 
<template>
  <child @clickFn="updateInfo" />
  <button @click="handelClick">传递给父级</button>
  <button @click="handelAdd">加</button>
  <button @click="handelDecrease">减</button>
</template>
 
<script setup lang="ts">
import child from './child.vue'
import { ref } from 'vue'
const num = ref(10)

const updateInfo = (userInfo) => {
  console.log(userInfo) // { name: '张三', age: 18,id: 1 }
}
const handelAdd = (n) => {
  num.value += n
}
const handelDecrease = (n) => {
  num.value -= n
}
 
</script>

还可以使用defineProps来暴露给父节点使用,例如:

const props = defineProps(["onSuccess"]);

场景: 父页面点击按钮,弹出对话框,对话框里面查询出来多条记录,选择其中一条记录给父页面的一个函数使用 , 项目实例:

父页面

<template>
  <div>
     <create-form-register
      ref="saveFormForRegister"
      @mySuccessFun="(val: any, text: any, areaUid: any)=>setProjectRegisterFun(val, text, areaUid)"
      :onSuccess="(val: any, text: any, areaUid: any) => setProjectRegisterFun(val, text, areaUid)"
    />
  <div>
</template>
<script lang="ts" setup>
...
import CreateFormRegister from "./components/queryRegisterDilog.vue";//子对话框组件


//对话框子页面需要调用的函数
const setProjectRegisterFun = (val: any, text: any, areaUid: any) => {
  console.info(val + "," + text + "," + areaUid);
}
</script>

子页面(使用defineProps 和defineEmits 经过测试都是可以的)

<template>
...
</template>
<script lang="ts" setup>
//对话框的确定按钮点击事件
//添加价格信息
const handleSubmit = async (isAll: boolean) => {
  let projectRegister = getCurrentRecord();
  if (!projectRegister) {
    ElMessage({
      message: "请至少选择一条数据",
      type: "warning",
    });
    return false;
  }
  handleCancel();
  //props.onSuccess(projectRegister.id, projectRegister.name, projectRegister.cprjNameEn);
  mySuccessFun(projectRegister);
};

const emit = defineEmits(["mySuccessFun"]);
const mySuccessFun = (projectRegister: any) => {
  // emit("mySuccessFun", {
  //   val: projectRegister.id,
  //   text: projectRegister.name,
  //   areaUid: projectRegister.cprjNameEn,
  // }); // 第一个参数为自定义事件名  第二个参数为要传递的数据
  emit(
    "mySuccessFun",
    projectRegister.id,
    projectRegister.name,
    projectRegister.cprjNameEn
  ); // 第一个参数为自定义事件名  第二个参数为要传递的数据
};

const props = defineProps(["onSuccess"]);//暴露函数onSuccess给父页面使用
defineExpose({ name: "", open });
</script>

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章