在vue中只存在两种关系,即 父子关系和非父子关系,而组件通信也有三种情况:
1.父子通信
2.子父通信
3.非父子通信
文章目录
想要贯通子父通信和非父子通信,首先要知道什么是自定义事件
1.自定义事件
只要组件标签上绑定的有事件,别管什么事件,他都是自定义事件
$emit 触发自定义事件
this.$emit('自定义事件名', '要传递的数据')
$on 监听自定义事件
this.$on('自定义事件名',(data)=>{
})
上面的data就是在$emit中,传递过来的数据,事件触发后想要执行相关操作,一定要先监听再触发。
this.$emit和this.$on的this必须是同一个实例对象,组件中的this及new Vue都包含$emit和$on
2.父子通信
父子通信,就是给组件标签添加属性,然后在子组件中通过设置props
接收父组件:
父组件 father
const Father = {
template: `
<div>
<Child msg="这是父组件中传递的数据" :num="num"></Child>
</div>
`,
data () {
return {
num: 1
}
}
}
子组件 child
const Child = {
template: `
<div>
{
{msg}} - {
{num}}
</div>
`,
// 像使用data一样使用props
props: {
msg: String,
num: Number
}
}
props不能直接修改,如果想要修改对应的数据,要找到数据源头进行修改
3.子父通信
子父通信和非父子通信都是借助自定义事件,但是监听写法有不同之处
父组件 father
const Father = {
template: `
<div>
{
{msg}}
<!-- 监听操作应该写在组件标签上 -->
<Child @自定义事件名="fn"></Child>
</div>
`,
methods: {
fn (data) {
// data就是子组件中传递来的数据
this.msg = data
}
},
data () {
return {
msg: "父组件中的数据"
}
}
}
子组件 child
const Child = {
template:`
<div>
<button @click="clickHandler">点击按钮将father中的msg修改</button>
</div>
`,
methods: {
clickHandler () {
this.$emit('自定义事件名', '要传递的数据')
}
}
}
4.非父子组件通信
非父子组件通信利用了自定义事件,但是因为组件不同,所以需要单独创建一个公共的vue实例(bus)来调用$emit和$on
公共vue实例: bus
const bus = new Vue()
farst
const farst = {
template: `
<div>
<button @click="clickHandler">点击传递数据到last中</button>
</div>
`,
methods: {
clickHandler () {
bus.$emit('自定义事件名', "从farst中传递的数据")
}
}
}
last
const last = {
template: `
<div>
{
{msg}}
</div>
`,
data () {
return {
msg: "这是last的数据"
}
},
created () {
bus.$on('自定义事件名', (data) => {
this.msg = data
})
}
}