Vue组件间通信方式解析(下篇)
2023-10-13 21:15:49
前言
在上一篇文章中,我们介绍了Vue组件间通信的前三种方式:props、emit/on和vuex。本篇接着上篇,继续介绍剩下的三种方式:attrs、listener和provide/inject。
attrs和listener
attrs和listener是Vue组件间通信的两种新方式,它们在Vue 2.3版本中被引入。attrs和listener都可以在组件的template中使用,用于在组件之间传递数据和事件。
$attrs
attrs是一个特殊的对象,它包含了父组件传递给子组件的所有属性,但不包括props。也就是说,attrs中的属性都是子组件不能识别的。我们可以通过在子组件的template中使用v-bind="attrs"来将attrs中的属性绑定到子组件的元素上。
<template>
<div>
<p>父组件传递的属性:</p>
<ul>
<li v-for="attr in $attrs">{{ attr }}: {{ $attrs[attr] }}</li>
</ul>
</div>
</template>
<script>
export default {
name: 'ChildComponent',
template
}
</script>
在上面的例子中,父组件可以通过在子组件的标签上添加属性来传递数据。例如:
<ChildComponent foo="bar" baz="qux"></ChildComponent>
在子组件中,我们就可以通过在template中使用v-bind="$attrs"来访问这些属性。例如:
<template>
<div>
<p>父组件传递的属性:</p>
<ul>
<li v-for="attr in $attrs">{{ attr }}: {{ $attrs[attr] }}</li>
</ul>
</div>
</template>
<script>
export default {
name: 'ChildComponent',
template
}
</script>
这样,在子组件中就可以访问到父组件传递的foo和baz属性。
$listener
listener是一个特殊的对象,它包含了父组件传递给子组件的所有事件监听器。也就是说,listener中的事件监听器都是子组件不能识别的。我们可以通过在子组件的template中使用v-on="listener"来将listener中的事件监听器绑定到子组件的元素上。
<template>
<div>
<button @click="$listener.handleClick">点击我</button>
</div>
</template>
<script>
export default {
name: 'ChildComponent',
template
}
</script>
在上面的例子中,父组件可以通过在子组件的标签上添加事件监听器来传递事件。例如:
<ChildComponent @handleClick="handleClick"></ChildComponent>
在子组件中,我们就可以通过在template中使用v-on="$listener"来访问这些事件监听器。例如:
<template>
<div>
<button @click="$listener.handleClick">点击我</button>
</div>
</template>
<script>
export default {
name: 'ChildComponent',
template
}
</script>
这样,在子组件中就可以监听父组件传递的handleClick事件。
provide/inject
provide/inject是Vue组件间通信的另一种新方式,它们在Vue 2.2版本中被引入。provide/inject允许父组件向其子组件提供数据和方法,而子组件可以通过inject来注入这些数据和方法。
provide
provide是一个对象,它包含了父组件想要提供给子组件的数据和方法。父组件可以通过在mounted钩子函数中使用this.provide()方法来提供数据和方法。例如:
export default {
name: 'ParentComponent',
data() {
return {
foo: 'bar'
}
},
mounted() {
this.provide({
foo: this.foo
})
}
}
在上面的例子中,父组件提供了一个名为foo的数据。
inject
inject是一个函数,它允许子组件注入父组件提供的数据和方法。子组件可以通过在mounted钩子函数中使用this.inject()方法来注入数据和方法。例如:
export default {
name: 'ChildComponent',
mounted() {
this.inject({
foo: 'foo'
})
}
}
在上面的例子中,子组件注入了父组件提供