返回

Vue组件间通信方式解析(下篇)

前端

前言

在上一篇文章中,我们介绍了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'
    })
  }
}

在上面的例子中,子组件注入了父组件提供