uni-app组件的通讯
1.父组件给子组件传值
父组件传递数据( :text动态绑定并传递属性text)给子组件,代码如下:
<template>
<view class="">
这是父组件页面,来自子组件的信息{{msg}}
<son :text= "text" @update="receiveMsg"/>
</view>
</template>
<script>
import son from './son.vue'
export default {
name:'father',
components: {
son
},
data() {
return {
text: 'hello',
msg:''
}
},
methods:{
receiveMsg(msg) {
this.msg = msg
}
}
}
</script>
<style>
</style>
子组件通过props来接受外界传递到组件内部的值代码如下:
template>
<view class="">
这是子组件页面,来自父组件的文本:{{text}}
<button type="primary" @click="sendMsg">点击子组件传递信息给父组件</button>
</view>
</template>
<script>
export default {
name:'son',
props: {
text: {
type: String,
default:''
}
},
data() {
return {
}
},
methods:{
sendMsg() {
this.$emit("update", 'world');
}
}
}
</script>
<style>
</style>
2.子组件给父组件传值
通过$emit触发事件进行传递参数
子组件代码:
<template>
<view class="">
这是子组件页面,来自父组件的文本:{{text}}
<button type="primary" @click="sendMsg">点击子组件传递信息给父组件</button>
</view>
</template>
<script>
export default {
name:'son',
props: {
text: {
type: String,
default:''
}
},
data() {
return {
}
},
methods:{
sendMsg() {
this.$emit("update", 'world');
}
}
}
</script>
<style>
</style>
父组件通过@监听自定义事件update,代码如下:
<template>
<view class="">
这是父组件页面,来自子组件的信息{{msg}}
<son :text= "text" @update="receiveMsg"/>
</view>
</template>
<script>
import son from './son.vue'
export default {
name:'father',
components: {
son
},
data() {
return {
text: 'hello',
msg:''
}
},
methods:{
receiveMsg(msg) {
this.msg = msg
}
}
}
</script>
<style>
</style>
2.兄弟组件通讯
需要借助uni.$emit
、uni.$on
、uni.$off
、uni.$once
,这四者常用于跨页面、跨组件通讯
1).先监听页面全局的自定义事件。事件可以由 uni.$emit 触发,回调函数会接收所有传入事件触发函数的额外参数
<template>
<view>
这是b组件:{{num}}
</view>
</template>
<script>
export default {
name:"TestB",
data() {
return {
num: 0
};
},
onLoad() {
console.log('onLoad');
// 测试组件有没有回调onLoad
},
created() {
console.log('created');
uni.$on("update",(num)=>{
this.num += num;
console.log('来自a组件的数据', num)
})
},
destroyed() {
console.log('destroyed');
// 因为事件监听是全局的,所以使用 uni.$on ,需要使用 uni.$off 移除全局的事件监听,避免重复监听
uni.$off("update");
}
}
</script>
<style>
</style>
2).触发事件
<template>
<view>
这是a组件 <button type="primary" @click="sendNum()">点击a组件传递num给b组件</button>
</view>
</template>
<script>
export default {
name:"TestA",
data() {
return {
};
},
methods:{
sendNum(num) {
setInterval(()=>{
uni.$emit("update", 1);
}, 2000)
}
}
}
</script>
<style>
</style>
3). 注意使用时,注意及时销毁事件监听,比如,页面 onLoad 里边 uni.$on
注册监听,onUnload 里边 uni.$off
移除,或者一次性的事件,直接使用 uni.$once
监听。
例子,未使用uni.$off
移除全局的事件监听,造成重复监听,A组件使用计时器每2秒触发事件一次,即使销毁了B组件,B组件依旧可以监听到。
解决方法,就是使用uni.$off
移除
destroyed() {
console.log('destroyed');
// 因为事件监听是全局的,所以使用 uni.$on ,需要使用 uni.$off 移除全局的事件监听,避免重复监听
uni.$off("update");
}
如果是一次性的事件,直接使用 uni.$once
监听,$once(eventName,callback)
监听全局的自定义事件。事件可以由 uni.$emit 触发,但是只触发一次,在第一次触发之后移除监听器
uni.$once("update",(num)=>{
this.num += num;
console.log('来自a组件的数据', num)
})