前言
上篇文章我们说到了props、
e
m
i
t
/
emit/
emit/on、vuex这三种组件之间的通信关系,本篇继上篇我们来说说
a
t
t
r
s
/
attrs/
attrs/listeners、provide/injedt、
p
a
r
e
n
t
/
parent/
parent/children和ref 上一篇:vue组件间通信六种方式(总结篇上)
一、Vue组件通信后三种?
a
t
t
r
s
/
attrs/
attrs/listeners、provide/injedt、
p
a
r
e
n
t
/
parent/
parent/children和ref
二 、 $attrs / $listeners
1.简介
多级组件嵌套需要传递数据时 ,通常使用的方法是通过vuex。 但如果仅仅是传递数据 ,而不做中间处理 ,使用 vuex 处理 ,未 免有点大材小用。 为此Vue2.4 版本提供了另一种方法 , 当一个组件没有声明任何 prop 时 ,这里会包含所有父作用域的绑定 (class 和 style 除外) ,并且可以通过 v-bind="$attrs" 传入内部组件。 通常配合 interitAttrs 选项一起使用 。
2.示例代码
代码如下(示例):
<template>
<div>
<child-com:foo="foo":boo="boo":coo="coo":doo="doo"></child-com>
</div>
</tempalte>
<script>
const childCom = ()=> import('./childCom1.vue')
export default {
data () {
return {
foo: 'Hello World!',
boo: 'Hello Javascript!',
coo: 'Hello Vue',
doo: 'Last'
}
},
components: { childCom }
}
</script>
<template>
<div>
<p>foo: {{ foo }}</p>
<p>attrs: {{ $attrs }}</p>
<child-com2 v-bind="$attrs"></child-com2>
</div>
</template>
<script>
const childCom2 = ()=> import('./childCom2.vue')
export default {
props: ['foo'],
inheritAttrs: false,
created () {
console.log(this.$attrs)
}
}
</script>
<template>
<div>
<p>boo: {{ boo }}</p>
<p>attrs: {{ $attrs }}</p>
<child-com3 v-bind="$attrs"></child-com3>
</div>
</template>
<script>
const childCom3 = ()=> import('./childCom3.vue')
export default {
props: ['boo']
inheritAttrs: false,
created () {
console.log(this.$attrs)
}
}
</script>
$attrs 表示没有继承数据的对象,格式为{属性名:属性值}。Vue2.4提供了 $attrs , $listeners 来传递数据与事件,跨级组件 之间的通讯变得更简单
三 、 provide/inject
1.简介
Vue2.2.0新增API,这对选项需要一起使用 , 以允许一个祖先组件向其所有子孙后代注入一个依赖 ,不论组件层次有多深 ,并 在起上下游关系成立的时间里始终生效 。 一言而蔽之 : 祖先组件中通过provider来提供变量 ,然后在子孙组件中通过inject来 注入变量
2.示例代码
代码如下(示例):
假设有两个组件 : A.vue 和 B.vue ,B 是 A 的子组件
export default {
provide: {
name: '浪里行舟'
}
}
export default {
inject: ['name'],
mounted () {
console.log(this.name);
}
}
可以看到 ,在 A.vue 里 ,我们设置了一个 provide: name ,值为 浪里行舟 ,它的作用就是将 name 这个变量提供给它的所有 子组件。 而在 B.vue 中 ,通过 inject 注入了从 A 组件中提供的 name 变量 ,那么在组件 B 中 ,就可以直接通过 this.name 访问这个变量了 ,它的值也是 浪里行舟。 这就是 provide / inject API 最核心的用法。 需要注意的是 : provide 和 inject绑定并不是可响应的 。 不过 ,如果你传入了一个可监听的对象 ,那么其对象的属性还是可响 应的。 所以 ,上面 A.vue 的 name 如果改变了 ,B.vue 的 this.name 是不会改变的 ,仍然是 浪里行舟。
四 、 $parent / $children 与 ref
1.简介
ref :如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素;如果用在子组件上,引用就指向组件实例 $parent / $children :访问父 / 子实例 需要注意的是:这两种都是直接得到组件实例,使用后可以直接调用组件的方法或访问数据。我们先来看个用 ref 来访问组件 的例子:
2.示例代码
代码如下(示例):
export default {
data () {
return {
title: 'Vue.js'
}
},
methods: {
sayHello () {
window.alert('Hello');
}
}
}
<template>
<component-a ref="comA"></component-a>
</template>
<script>
export default {
mounted () {
const comA = this.$refs.comA;
console.log(comA.title);
comA.sayHello();
}
}
</script>
不过, 这两种方法的弊端是,无法在跨级或兄弟间通信 。
<component-a></component-a>
<component-b></component-b>
<component-b></component-b>
我们想在 component-a 中,访问到引用它的页面中(这里就是 parent.vue)的两个 component-b 组件,那这种情况下,就得 配置额外的插件或工具了,比如 Vuex 和 Bus 的解决方案。
总结
常见使用场景可以分为三类: 父子通信: 父向子传递数据是通过 props,子向父是通过 events( $emit );通过父链 / 子链也可以通信( $parent / $children );ref 也可以访问组件实例;provide / inject API。 兄弟通信: Bus;Vuex; 跨级通信: Bus;Vuex;provide / inject API、
a
t
t
r
s
/
attrs/
attrs/listeners
以上就是vue组件间通信六种方式(总结篇下),原创不易,期待您的点赞关注与转发评论😜😜😜
|