关于vue中父子通信的理解 (有详细过程与解读)
这里
所有代码
纯属直接csdn手敲,大家看下就好,哪个地方报错了就阿巴阿巴阿巴…
关于vue中父子通信,大家或许知道是有props与事件触发两种方式(不知道的当我提前剧透了哈~)。
①父传子 [通过props]
那假如我现在有一个需求:假设父组件通过请求服务器已经拿到了数据,现在需要把数据展示到网页上面。但是我们划分了层次(如下)。
- 父组件list(我拿到了数据)
- 子组件(list-item) (我要展示数据)
现在我们需要把数据从list传到list-item中,也就是父传子,这种是最简单不过的了。
list.vue
<template>
<list-item :list="list"/>
</template>
<script>
new Vue({
component: {
list-item
},
data(){
return {
list: [
//...
]
}
}
})
</script>
list-item.vue
<template>
<div>
{{list}}
</div>
</template>
<script>
new Vue({
props: {
list
}
})
</script>
②子传父 [通过props](与①一致,未改动)
- 父组件list(第二步:好的,我知道数据要变了...)
- 子组件(list-item) (第一步:告诉你,数据要变了!)
现在我们需要把数据从list传到list-item中,也就是父传子,这种是最简单不过的了。
代码和刚才的父传子[通过props]是一模一样的!!!啥子?你问我为啥要在写一次…可能是为了水字数吧
那么为什么同样的代码也能实现这个功能呢?大家想啊,我现在是不是要监控list-item里面的值发生了改变,并且告诉list,我!变!了!
那我现在把数组从list.vue传给list-item.vue,当我传进去的数组发生改变的时候,是不是会触发vue的响应式?那是不是也间接的告诉了list数组发生了改变?算是一种投机取巧吧…
list.vue
<template>
<list-item :list="list"/>
</template>
<script>
new Vue({
component: {
list-item
},
data(){
return {
list: [
//...
]
}
}
})
</script>
list-item.vue
<template>
<div>
{{list}}
</div>
</template>
<script>
new Vue({
props: {
list
}
})
</script>
③子传父 [通过$emit]
zi: 子组件里面到时候要用到事件名
fu: 父组件
list.vue
<template>
<list-item :list="list" @zi="fu"/>
</template>
<script>
new Vue({
component: {
list-item
},
data(){
return {
list: [
//...
]
}
},
methods: {
fu(value) {
console.log("我被触发啦~");
}
}
})
</script>
list-item.vue
<template>
<div >
{{list}}
<button @click="test">clicke me</button>
</div>
</template>
<script>
new Vue({
props: {
list
},
methods: {
test() {
this.$emit("zi","随便给你一个数据吧~")
}
}
})
</script>
我们先来看看这行代码<list-item :list="list" @zi="fu"/>
,怎么理解这代码的意思呢?其实很简单。
我们先在list.vue中绑定事件,本着点谁,就在谁身上加的原则,我们给list-item中添加一个点击事件,那么要先理解list-item是一个组件的实例对象,
也就是说,我们给list-item这个组件实例化的对象添加了一个名为zi的点击事件,并且当我们触发这个名为zi的点击事件的时候,会触发这个名为fu的事件。
再来看看这行代码<button @click="test">clicke me</button>
,很简单,当我们点击这个按钮的时候会触发test事件,而test事件也很简单,只有一行代码,test() { this.$emit("zi") }
,我们看到$emit这个关键字,也可以理解为触发的意思,我们触发了list-item这个示例上面的zi方法。
这不就首尾呼应了?
芜湖 笑死,根本笑不死 阿巴阿巴阿巴(装傻~)
总的来说就是:
- 父组件中
- @事件名=“回调名”
- 注册回调函数
- 子组件中
- 绑定click事件@click=“子组件中随便一个函数名”
- 这随便一个函数名中: this.$emit(“事件名”)
④子传父 [通过$ref]
list.vue
<template>
<list-item :list="list" ref="listItem"/>
</template>
<script>
new Vue({
component: {
list-item
},
data(){
return {
list: [
//...
]
}
},
methods: {
fu(value) {
console.log("我被触发啦~");
}
},
mounted() {
this.$refs.listItem.$on("fu", value)
}
})
</script>
list-item.vue
(与③中的 list-item.vue 一致,未改动)
<template>
<div >
{{list}}
<button @click="test">clicke me</button>
</div>
</template>
<script>
new Vue({
props: {
list
},
methods: {
test() {
this.$emit("zi","随便给你一个数据吧~")
}
}
})
</script>