vue源码-vue组件通信方式
Posted suwu150
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了vue源码-vue组件通信方式相关的知识,希望对你有一定的参考价值。
vue源码(二)-vue组件通信方式
一、组件化
组件化开发能够提高开发效率,方便重复使用
简化调试步骤,提升项目的可维护性,便于多人系统开发
二、通信方式
1.父组件->子组件
1.1通过属性props进行传递
子组件进行定义一个字段msg接受父组件传递的参数
<template>
<div class="hello">
<h3> msg </h3>
</div>
</template>
<script>
export default
name: 'HelloWorld',
props:
msg: String
</script>
<style scoped>
h3
margin: 40px 0 0;
</style>
上述代码中,通过对props中msg的限定,进行接收有父组件传递下来的内容,然后在模版文件中通过插槽表达式进行使用。
<HelloWorld msg="用于prop传递参数给子组件"/> // 父组件通过msg进行传递参数
1.2vm.$attrs
-
只读
包含了父作用域中不作为 prop 被识别 (且获取) 的特性绑定 (
class
和style
除外)。当一个组件没有声明任何 prop 时,这里会包含所有父作用域的绑定 (class
和style
除外),并且可以通过v-bind="$attrs"
传入内部组件——在创建高级别的组件时非常有用。
<template>
<div class="hello">
<p>$attrs.foo </p>
</div>
</template>
<script>
export default
name: 'HelloWorld'
</script>
<style scoped>
h3
margin: 40px 0 0;
</style>
上述代码,通过$attrs属性进行获取由父组件传递的参数foo,这种方式用于获取在子组件中props中没有声明的属性,在父组件中使用和1.1使用方式一致
<HelloWorld foo="测试$attrs.foo"/> // 父组件通过foo进行传递参数
1.3 vm.$refs
-
只读
一个对象,持有注册过
ref
特性 的所有 DOM 元素和组件实例。通过给子组件添加ref的形式进行传递数据如下所示:
<template> <div class="hello"> <p> age </p> </div> </template> <script> export default name: 'HelloWorld', data: () => return age: '30' </script> <style scoped> h3 margin: 40px 0 0; </style>
子组件中有数据age,我们能够在父组件中通过this.$refs.hw.age = '18'
的方式进行修改age属性值
1.4 vm.$children-子元素
-
只读
当前实例的直接子组件。**需要注意
$children
并不保证顺序,也不是响应式的。**如果你发现自己正在尝试使用$children
来进行数据绑定,考虑使用一个数组配合v-for
来生成子组件,并且使用 Array 作为真正的来源。
与1.3同样的子组件,在父组件通信时,只需要使用this.$children[0].age = '20';
方式进行处理age的值即可
2.子组件->父组件通信
通过注册自定义事件监听的方式进行传递,通过 @click="$emit(‘clickDiv’)"进行派发事件,然后父组件处理的方式
<template>
<div class="hello" @click="$emit('clickDiv')">
<h3> msg </h3>
</div>
</template>
<script>
export default
name: 'HelloWorld',
props:
msg: String
,
data: () =>
return
age: '30'
</script>
<style scoped>
h3
margin: 40px 0 0;
</style>
父组件中需要对事件进行监听
<div id="app">
<HelloWorld
msg="用于prop传递参数给子组件"
foo="测试$attrs.foo"
ref="hw"
@clickDiv="onMyClick"
/>
其中onMyClick是父组件中方法,用于处理clickDiv传递的数据
3.兄弟之间通信:通过共同的祖辈组件通信
一般通过$parent
和 $root
进行处理,利用组件的生命周期进行监听事件,然后进行处理兄弟节点传递的数据
在每个需要监听的兄弟节点中添加下面监听事件
created()
// 监听事件
this.$parent.$on('hiBrother', () =>
console.log('来自兄弟的问候', 'HelloWorld');
);
,
接着在需要通过兄弟节点的地方进行调用如下代码:
this.$parent.$emit('hiBrother');
通过上述方式,就能够实现兄弟之间的通信
4.祖先和后代之间
由于嵌套层级过多,传递props不切合实际,可使用provide/inject API完成该任务
provide / inject:
这对选项需要一起使用,以允许一个祖先组件向其所有子孙后代注入一个依赖,不论组件层次有多深,并在起上下游关系成立的时间里始终生效。如果你熟悉 React,这与 React 的上下文特性context很相似。
provide
选项应该是一个对象或返回一个对象的函数。该对象包含可注入其子孙的属性。在该对象中你可以使用 ES2015 Symbols 作为 key,但是只在原生支持 Symbol
和 Reflect.ownKeys
的环境下可工作。
inject
选项应该是:
- 一个字符串数组,或
- 一个对象,对象的 key 是本地的绑定名,value 是:
- 在可用的注入内容中搜索用的 key (字符串或 Symbol),或
- 一个对象,该对象的:
from
属性是在可用的注入内容中搜索用的 key (字符串或 Symbol)default
属性是降级情况下使用的 value
在父组件进行提供值:
// ancestor
provide()
return
provideFoo: '测试provide/inject传递信息'
,
在子组件中进行使用注入值:
// descendant
inject:
provideFoo: default: '这里设置默认值'
,
// 或者使用数组形式
inject: ['provideFoo']
5.任意两个组件之间:事件总线或vuex
- 事件总线:创建一个公共类负责事件派发、监听和回调管理
// EventEmit:事件派发、监听和回调管理
export default class EventEmit
constructor()
this.callbacks = ;
$on(name, fn)
this.callbacks[name] = this.callbacks[name] || [];
this.callbacks[name].push(fn);
$emit(name, args)
if (this.callbacks[name])
// 存在 遍历所有callback
this.callbacks[name].forEach(cb => cb(args));
上述代码,使用$on
进行注册全局监听事件、使用$emit
进行通知全局处理事件.
当然我们需要将这个公共处理事件类挂在Vue原型上:
import Vue from "vue";
import App from "./App.vue";
import EventEmit from './utils/eventEmit';
// main.js
// 事件总线方式,挂载到Vue中
Vue.prototype.$eventEmit = new EventEmit();
new Vue(
data:
bar: 'bar'
,
render: h => h(App),
).$mount("#app");
在需要使用监听的地方进行添加监听
// 创建事件总线
this.$eventEmit.$on('fromHelloWorld', (value) =>
alert('监听到由hello world组件传递来的数据:' + value);
);
在传递触发的组件中进行触发
// 派发事件,在HelloWorldEmit.vue组件中监听
this.$eventEmit.$emit('fromHelloWorld', '传递给HelloWorldEmit.vue的数据');
触发的同时,通过第二个参数进行传值。
以上就是组件之间通信的各种方式。
以上是关于vue源码-vue组件通信方式的主要内容,如果未能解决你的问题,请参考以下文章