Vue3 组件化开发(5)——组件间的通信(4)

170 阅读1分钟

「这是我参与2022首次更文挑战的第28天,活动详情查看:2022首次更文挑战」。

子组件传递给父组件

  • 什么情况下子组件需要传递内容到父组件中呢?
    • 子组件有一些事件发生的时候,比如在组件中发生了点击,父组件需要切换内容;
    • 子组件有一些内容想要传递给父组件的时候;
  • 那么,如何完成上面的操作呢?
    • 首先,我们需要在子组件中定义好在某些情况下会触发的事件的名称;
    • 然后,在子组件中发生某个事件的时候,触发上一步中已定义好名称了的某个事件
    • 最后,在父组件中以 v-on 的方式传入要监听的事件名称,并且绑定到对应的方法中;

自定义事件的流程

我们拿计数器来举例:CounterOperation.vue(子组件)中有两个按钮,分别用来加一和减一,每次点击加一或减一按钮,都通过 this.$emit() 的方式发送事件给 App.vue(父组件),然后父组件中监听到事件后再把最新的计数结果更新到父组件中的元素上。代码如下:

父组件 App.vue

<template>
  <div>
    <h2>当前计数:{{ counter }}</h2>

    <counter-operation @add="addOne" @sub="subtractOne" />
  </div>
</template>

<script>
  import CounterOperation from './CounterOperation.vue'

  export default {
    components: {
      CounterOperation
    },
    data() {
      return {
        counter: 0
      }
    },
    methods: {
      addOne() {
        this.counter++
      },
      subtractOne() {
        this.counter--
      }
    }
  }
</script>

<style scoped>

</style>

子组件 CounterOperation.vue

<template>
  <div>
    <button @click="increment">+1</button>
    <button @click="decrement">-1</button>
  </div>
</template>

<script>
  export default {
    // 在 Vue 3 中,当前组件中要发送出去的事件都需要先在 emits 中进行注册
    emits: ['add', 'sub'],
    methods: {
      increment() {
        console.log('+1');
        this.$emit('add')
      },
      decrement() {
        console.log('-1');
        this.$emit('sub')
      }
    }
  }
</script>

<style scoped>

</style>

自定义事件的参数

上面的代码中,子组件发出事件父组件监听的过程中是没有传递任何参数的,但有时候我们可能需要传递一些参数,举个例子,假如我们想要根据我们输入的数值来进行加减,就可以这样做:

父组件 App.vue

<template>
  <div>
    <h2>当前计数:{{ counter }}</h2>

    <counter-operation @add="addOne" @sub="subtractOne" @addN="addNNum" />
  </div>
</template>

<script>
  import CounterOperation from './CounterOperation.vue'

  export default {
    components: {
      CounterOperation
    },
    data() {
      return {
        counter: 0
      }
    },
    methods: {
      addOne() {
        this.counter++
      },
      subtractOne() {
        this.counter--
      },
      addNNum(num, name, age) {
        this.counter += num
        console.log(name, age);
      }
    }
  }
</script>

<style scoped>

</style>

子组件 CounterOperation.vue

<template>
  <div>
    <button @click="increment">+1</button>
    <button @click="decrement">-1</button>

    <input type="text" v-model.number="num">
    <button @click="incrementN">+n</button>
  </div>
</template>

<script>
  export default {
    // 在 Vue 3 中,当前组件中要发送出去的事件都需要先在 emits 中进行注册
    emits: ['add', 'sub', 'addN'],
    data() {
      return {
        num: 0
      }
    },
    methods: {
      increment() {
        console.log('+1');
        this.$emit('add')
      },
      decrement() {
        console.log('-1');
        this.$emit('sub')
      },
      incrementN() {
        // 可以传递多个参数
        this.$emit('addN', this.num, 'coderzhj', 20)
      }
    }
  }
</script>

<style scoped>

</style>