一、父子傳值(props / $emit 、ref / $refs)
1、props / $emit
父組件通過?props
?向子組件傳遞數據,子組件通過?$emit
?觸發事件向父組件傳遞數據。
?父組件:
// 父組件中<template><view class="container"><view class="row" v-for="(item, index) in listData" :key="item.pkId"><newsbox pageTitle="待辦" :itemInfo="item"></newsbox></view></view>
</template>
<script setup>import { ref } from 'vue';
let listData = ref([{name: "張三", age: "18"}, {name: "李四", age: "19"}])</script>
<style lang="scss" scoped>
.container{padding: 10rpx 30rpx;.row{padding: 10rpx 0;}
}
</style>
子組件:
// 子組件中<template><view class="box"><text class="title">{{pageTitle}}</text> <text class="name">{{itemInfo.name}}</text> </view>
</template>
<script setup>defineProps({itemInfo: {type: Object,default: {}},pageTitle: {type: String,default: ""}})
</script>
<style lang="scss" scoped>
.box {.title {font-size: 32rpx;}.name {font-size: 28rpx;}
}
</style>
二、兄弟傳值( $emit / $on )
借助中間代理,?$emit
?和?$on
1、說明
uni.$emit(eventName,OBJECT)
觸發全局的自定義事件,附加參數都會傳給監聽器回調函數。
HarmonyOS Next 兼容性
?
代碼示例
uni.$emit('update',{msg:'頁面更新'})
uni.$on(eventName,callback)
監聽全局的自定義事件,事件由?uni.$emit
?觸發,回調函數會接收事件觸發函數的傳入參數。
HarmonyOS Next 兼容性
?
代碼示例?
uni.$on('update',function(data){console.log('監聽到事件來自 update ,攜帶參數 msg 為:' + data.msg);
})
uni.$off(eventName, callback)
移除全局自定義事件監聽器。
HarmonyOS Next 兼容性
?
Tips
- 如果uni.$off沒有傳入參數,則移除App級別的所有事件監聽器;
- 如果只提供了事件名(eventName),則移除該事件名對應的所有監聽器;
- 如果同時提供了事件與回調,則只移除這個事件回調的監聽器;
- 提供的回調必須跟$on的回調為同一個才能移除這個回調的監聽器;
代碼示例
$emit
、$on
、$off
常用于跨頁面、跨組件通訊,這里為了方便演示放在同一個頁面
<template><view class="content"><view class="data"><text>{{val}}</text></view><button type="primary" @click="comunicationOff">結束監聽</button></view></template><script>export default {data() {return {val: 0}},onLoad() {setInterval(()=>{uni.$emit('add', {data: 2})},1000)uni.$on('add', this.add)},methods: {comunicationOff() {uni.$off('add', this.add)},add(e) {this.val += e.data}}}</script><style>.content {display: flex;flex-direction: column;align-items: center;justify-content: center;}.data {text-align: center;line-height: 40px;margin-top: 40px;}button {width: 200px;margin: 20px 0;}</style>
注意事項
- uni.$emit、 uni.$on 、 uni.$once 、uni.$off 觸發的事件都是 App 全局級別的,跨任意組件,頁面,nvue,vue 等
- 使用時,注意及時銷毀事件監聽,比如,頁面 onLoad 里邊 uni.$on 注冊監聽,onUnload 里邊 uni.$off 移除,或者一次性的事件,直接使用 uni.$once 監聽
- 注意 uni.$on 定義完成后才能接收到 uni.$emit 傳遞的數據
eventName
?應避免使用?uni
?開頭,以免與 uni-app 內置事件沖突
三、provide/inject
簡單講解:provide和inject叫依賴注入,是vue官方提供的API,它們可以實現多層組件傳遞數據,無論層級有多深,都可以通過這API實現。
假設這是太老爺組件: provide(‘名稱’, 傳遞的參數)向后代組件提供數據, 只要是后代都能接收
<template><div></div>
</template><script setup>
import { ref, provide } from 'vue'
const name = ref('天天鴨')
// 向后代組件提供數據, 只要是后代都能接收
provide('name', name.value)
</script>
最深層的孫組件: 無論層級多深,用 inject(接收什么參數) 進行接收即可?
<template><div>{{ name }}</div>
</template><script setup>
import { inject } from 'vue'
// 接收頂層組件的通信
const name = inject('name')
</script>