11 【组件通信】
1.props
Section titled “1.props”适用于的场景:父子组件通信
注意事项:
如果父组件给子组件传递数据(函数):本质其实是子组件给父组件传递数据
如果父组件给子组件传递数据(非函数):本质就是父组件给子组件传递数据
书写方式:3种
特殊情况:路由传递props 1:布尔值类型,把路由中params参数映射为组件props数据 2:对象,静态数据,很少用 3:函数,可以把路由中params|query参数映射为组件props数据
2.自定义事件
Section titled “2.自定义事件”使用于场景:子组件给父组件传递数据
$on与$emit
- $emit绑定一个自定义事件event,当这个这个语句被执行到的时候,就会将参数arg传递给父组件,父组件通过@event监听并接收参数。
3.全局事件总线$bus
Section titled “3.全局事件总线$bus”使用于场景:万能
组件实例的原型的原型指向的Vue.prototype
Vue.prototype.$bus = this;
- 对于比较小型的项目,没有必要引入 vuex 的情况下,可以使用 eventBus。
- 它的实现思想也很好理解,在要相互通信的两个组件中,都引入同一个新的vue实例,然后在两个组件中通过分别调用这个实例的事件触发和监听来实现通信。
4.pubsub-js
Section titled “4.pubsub-js”适用于场景:万能
vue当中几乎不用(因为vue中有全局事件总线和这个第三方提供的库功能重复)
在React框架中使用比较多(发布与订阅)
5.Vuex
Section titled “5.Vuex”适用于场景:万能
数据非持久化
核心概念: State:保存所有组件的共享状态 Getters:类似状态值的计算属性 Mutations:修改 State中状态值的唯一方法,里面包含状态变化监听器和记录器 Actions:用于异步处理 State中状态值,异步函数结束后调用Mutations Modules:当一个 State 对象比较庞大时,可以将 State 分割成多个Modules 模块。
适用于场景:父子组件通信 --- (结构)
默认插槽 具名插槽 作用域插槽:子组件的数据来源于父组件,但是子组件的自己的结构有父亲决定。
- 插槽就是子组件中的提供给父组件使用的一个占位符,用
<slot></slot>表示,父组件可以在这个占位符中填充任何模板代码,如 HTML、组件等,填充的内容会替换子组件的<slot></slot>标签。
- 可以实现任意组件的通信的方法有两个:事件总线 和 Vuex,事件总线难维护数据但轻量,Vux维护数据方便但比较重量。
- 可以实现父与子孙跨越层级通信的方法也有两个:
$attrs/$listeners和provide/inject,$attrs/$listeners具有响应性且可以双向通信,provide/inject无响应性且只能单向通信(父传子) - 只能实现父与子组件通信的方法有一个:
props/emit,方法比较基础,适合只有父子组件通信的方法,若想跨层级通信需要中间组件做转发,比较麻烦。
8.v-model
Section titled “8.v-model”CustomInput.vue
ModelTest.vue

9.属性修饰符.sync
Section titled “9.属性修饰符.sync”9.1 基础结构
Section titled “9.1 基础结构”SyncTest.vue

效果:

9.2 不使用sync修饰符
Section titled “9.2 不使用sync修饰符”SyncTest.vue
Child.vue
效果:


9.3 使用sync修饰符
Section titled “9.3 使用sync修饰符”:money.sync,代表父组件给子组件传递props[money],给当前子组件绑定一个自定义事件(update:money)
10. $attrs和$listeners
Section titled “10. $attrs和$listeners”10.1 封装ElementUI按钮,并且是带Hover提示的按钮
Section titled “10.1 封装ElementUI按钮,并且是带Hover提示的按钮”新建HintButton,里面放一个index.vue,这个文件用来封装按钮

AttrsListenersTest.vue
HintButton
这回我们子组件接收父组件传递过来的参数,我们就不用props了,我们利用组件实例身上的一个属性$attrs也可以接收父组件传递给子组件的数据
在子组件中打印一下$attrs

我们注释props:['title'],利用$attrs接收参数的时候,会发现参数全部接收到了

我们打开props:['title'],利用$attrs接收参数的时候,会发现参数除了props接收的title,其他参数都被$attrs接收了

所以,这里可以总结为:对于子组件而言,父组件给的数据可以利用props接收,注意,如果子组件通过props接收的属性,在$attrs属性当中是获取不到的
因为我们需要封装ElementUI按钮,并且是带Hover提示的按钮
在HintButton/index.vue中:
我们在el-button外面来一个a标签,因为a标签有一个title属性,就带有提示功能

10.2 $listeners获取父组件给子组件传递的自定义事件
Section titled “10.2 $listeners获取父组件给子组件传递的自定义事件”这个时候我们想给按钮绑定一个点击事件,点击弹出一个666什么的,我们知道HintButton是一个组件,在组件身上写@click他就变成了自定义事件了
@click.native其实是可以解决的,但是我们这里有另外的解决办法,所以我这样来演示:
父组件绑定自定义事件

我们想给HintButton绑定单击事件 实际上是给el-button绑定单击事件
我们先看看$listeners身上有没有父组件传递过来的自定义事件,并且利用v-on来给el-button绑定单击事件
在HintButton/index.vue中:
子组件中

打印发现:$listeners确实可以获取父组件给子组件传递的自定义事件

此时我们再点击一个按钮,会发现成功弹出了666

10.3 总结
Section titled “10.3 总结”$listeners与$attrs(组件通信方式的一种)
他们两者都是组件实例的属性,可以获取到父组件给子组件传递的props与自定义事件