vue:父子组件的通信

上一篇:vue组件化开发

在上一篇文章中,我们申明了一点,那就是组件之间是独立的,除非构建了通信。

组件间为什么要构建通信?

在单一文件中写上整个网站的代码逻辑,这无疑使得维护成本巨大。所以我们选择了组件化开发,把组件间独立起来,这样谁也不干涉谁,是谁的逻辑就在谁的文件中实现,最后串在一起,一个网站内容就大功告成了。那父子组件的通信有什么用呢?

我们不妨设想一个场景:在点外卖时,当我们选中某个餐品,下面的计价开始变化,甚至还会计算一下是否满配送,在淘宝购物车中,当我们清空一些商品时,下面也会有总价的变化,或者如果我们想要两个相同组件却拥有不同的反馈,比如两个按钮,一个按钮为提交,一个按钮为回退,但他们来自同一个组件,该怎么为他们添加事件呢?

以上的所有情况我们都可以通过父级组件为子组件提供数据来完成,通过props我们可以为子组件添加Number,String,Object,Array,甚至Function。并且,增加了组件间的通信也表现出了vue的弹性,我们是可以根据自己意愿来添加组件联系的。

组件的通信实现

想要实现组件间的通信,得有一方得发出信息,另一方接收信息,然后返回信息使对方接收到信息,这就是双向通信,但是不是每个组件都是双向通信,我们也可以父级组件单传数据,也可以使子组件单传数据给父组件。

父组件单传子组件

父组件





子组件





 首先,在传输数据前,我们是不是得对一个暗号?这个暗号就是属性名,父组件动态绑定的属性名要与子组件props中的一致,无关顺序。子组件获得来自父组件的数据后就可以使用了。当然,props不只有数组表达形式,还有对象形式。





props对象形式中支持我们为传入的数据类型进行一个限制,但是这种限制比较弱,只会提醒一下你,而不会报错。props还有一种形式,这种形式更加完备,我们可以为传输的数据添加默认值,这样即使父级组件没有传入数据也会正常渲染。





非props

形象来说,就是没对上暗号的那些数据该怎么办?

在vue中,这些数据并不会直接丢掉,而是挂在子组件的根节点上,如果有两个根节点会发生什么?

什么都不会发生,会报个错然后让你选取一个根节点来挂载非props数据。

我们可以使用$attrs来访问所有的非props的属性。 

子组件单传父组件

自定义事件

App.vue





 addCounter.vue





 subCounter.vue





先来简述一下上述代码功能:

我们分别有+1,+5,+10的三个按钮以及与之对应的减法按钮,当我们点击这些按钮后,位于父组件的counter发生相应的变化。

首先,我们想到的就是在子组件addCounter中创建一个方法increment,传入参数,可以控制为counter加一定的值,再在subCounter中创建一个方法decrement,传入参数,控制counter减一定的值。而counter我们可以通过父组件传过来,计算后的counter在写个方法让父组件监听,父组件得到值后再赋值给counter渲染。

这个方法是可行的。代码如下:

App.vue





increment.vue





这样的确能实现目的,但是却不建议这么做,这相当于是把运算过程放在了子组件中,仅仅是把结果返回给父组件。但在实际开发中,我们不一定只开发这么简单的功能,运算或许没这么简单,况且,按下+1按钮给我返回1才符合逻辑吧?我们并不需要子组件干这么多不属于它的活。

下面是另外的一种思路:

对于子组件,不需要父组件给我任何数据,我只需要知道用户按下了哪一个按钮任何返回那个按钮的数值,这样我只需要在点击按钮中释放事件并且把数值传给释放事件中,父组件只需要监听到我这个事件,那任务就结束了。父组件接到子组件传来的值,这时,它可以对这个值做任何操作,这就使得我们有更多的操作空间。

而这就对应着一开始的代码,对比两种思路的代码,你会发现第二种思路的方式组件之间更加独立,至少我们不需要改逻辑的时候跑到子组件的方法中改。

props接收函数的情况

父级组件



 子组件



这结合了后面composition api的内容,但大体是一样的,这里我们做出的效果就是相同的两个组件拥有不同的方法,我们向子组件传入函数,这个用传统方法一直搞不出来,难受。最后只能用composition api来替代了,我有时间再试试。回到正题,我们传入methodA,子组件接收到这个函数,当点击按钮时,就会调用接收的函数。

你可能感兴趣的:(Python全栈开发,vue.js,前端,javascript,ecmascript,前端框架,css)