“我报名参加金石计划1期挑战——瓜分10万奖池,这是我的第1篇文章,点击查看活动详情”
前言
vue的两大核心:
- 数据驱动
- 组件系统
组件中最重要的就是通信,但是组件实例的作用域又都是独立的,有时候又需要不同组件间进行数据相互引用,所以我们就来讨论一下组件间通信的几种方式吧。
props
props一般用于父组件向子组件传值,在这里先贴一个官网props的用法,毕竟已官网为准嘛,然后我们再举个例子慢慢讲解props
现在让我们开始吧!
我们可以把props的写法分为三种
- 数组写法
- 简单的对象写法
- 复杂的对象写法
这三种写法都比较简单,但是既然出现了多种写法说明简单的写法会出现些说明bug,首先我们先来看数组的写法
浏览器显示:
首先在父组件那里给子组件定义了一个自定义属性,属性里面的值是常量,当然也可以传变量,但是为了演示问题,所以我们就用常量了。
然后子组件需要接收父组件传过来的值,利用props来接收,数组的接收方式比较简单,就是直接用字符串接收,这个字符串需要和父组件那里的自定义属性一致
在浏览器看的结果也是 没有错的,然后假设现在我们有一个需求是需要将每个学生的年龄全部都加一,这个需求很简单,我们就直接在子组件那里把年龄加一即可,然后你就会看见他们的年纪已经不敢是学生了。。。。
这是因为我们传过去的值是个字符串,这个真的是个很容易踩的坑,因为写vue写习惯以后,就会潜意识认为那个双引号里就是个表达式。所以这时候解决方式最简单的就是给每个关于年纪的自定义属性加一个v-bind,那么就可以解决了,但是有时候你确实就是不知道到底错那了,所以我们引出对象的写法
我们给每个props属性都加上一个类型限制,可以看到在这里我们给年纪设置了必须是number类型的,这时候看控制台就会报错,并且报错说明非常明白。
那么如果你想限制的更严谨一点的话,可以写的再多一点,比如是否必传,是否有默认值之类的(这里注意对象和数字的默认值需要是一个函数的返回值)
$emit
说完父传子,那么就来说一下子传父该怎么传,我们可以利用$emit方法,父组件监听使用@(v- on)进行监听,然后进行方法处理。
这里的过程是,点击按钮以后,调用changeName函数,随后利用$emit通知父组件那里监听的自定义事件xx,随后xx的回调changeName执行了,改变了数据源,随后重新渲染模板
全局事件总线
父子之间的通信是解决了,但是还有兄弟姐妹之间的呢,这个可以通过全局事件总线来实现,它就像是所有组件共用相同的事件中心,可以向该中心注册发送事件或接收事件, 所以组件都可以通知其他组件。
首先在vue的原型上先整一个全局都要用的'公共汽车',在需要接收数据的组件通过emit去通知(相当于车上的人要在指定的站牌下车),具体可以看下面这个示例
main.js
gege.vue和didi.vue
点击两个按钮以后
我们来捋一下执行过程:首先在gege.vue和didi.vue的mounted函数里面我们分别放置了两个站牌用来接收别人传过来的值,$on的第一个参数是事件的名字,可以认为是站牌的名字,第二个参数的事件的回调,形参接收的是别人传过来的值,随后我们点击了修改哥哥那里的值的按钮,触发changeGeGe函数,随后调用changeGeGe这个’站牌‘,并且还传了一个’弟弟那里传过来的值‘过去,随后在gege.vue那里的this.gege = arg触发了,于是重新渲染模板....点击哥哥那里的按钮也是一样的步骤。
相信到这里大家也会觉得全局事件总线有点乱,项目小一点还好,如果项目大一点就很难维护了。
v-model
有时候我们希望父子组件公用一个数据,又不想通过props去实现的话,就可以使用v-model来实现
linteners
多层嵌套组件传递数据时,如果只是传递数据,而不做中间处理的话就可以用这个,比如父组件向孙子组件传递数据时 attrs" linteners"
父:
子:
孙:
parent/root
可以通过一个组件拿到它的父亲组件或者孩子组件,拿到了说明掌握了父组件的数据和方法以及子组件的数据和方法啊,那你不是想怎么操作怎么操作嘛
这个比较简单,我们直接就是以上面的为例子,直接打印出父子组件
父子组件都拿到了就随便你操作了,想改变父组件的数据就改,想改子组件的数据也随便改,但是这个也是又缺陷的,如果说嵌套层级太深了,那这个也不好用。
与之类似的还有root,root则是可以拿到APP.vue里的数据和方法
vuex
当然必不可少的就是vuex了,但是这个内容算有点多了,到时候我另写一篇文章仔细讲讲,那么就感谢大家看到这里啦