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>

 

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