欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

关于vue中父子通信的理解 (有详细过程与解读)

程序员文章站 2022-03-16 17:44:05
...

这里所有代码纯属直接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>