Vue $emit() 方法

随着内置$emit()Vue 中的方法我们可以在子组件中创建一个可以在父元素中捕获的自定义事件。

props 用于将数据从父元素发送到子组件,并且$emit()用于执行相反的操作:将信息从子组件传递到父组件。

对象接下来我们要做的事情是最终在父级中更改食品的“最喜欢”状态App.vue而不是在FoodItem.vue当前正在发生更改的子组件。

原因用于更改收藏夹状态App.vue而不是在FoodItem.vue就是它App.vue是最喜欢的状态首先存储的位置,因此需要更新。在较大的项目中,数据可能来自我们连接的数据库App.vue,并且我们希望组件发生更改以在数据库中进行更改,因此我们需要从子组件与父组件进行通信。

发出自定义事件

需要从组件向父级发送信息,我们使用内置方法$emit()要做到这一点。

我们已经拥有了toggleFavorite里面的方法FoodItem.vue单击切换按钮时运行的组件。现在让我们删除现有的行并添加一行来发出我们的自定义事件“toggle-favorite”:

FoodItem.vue:

methods: {
  toggleFavorite() {
    this.foodIsFavorite = !this.foodIsFavorite;
    this.$emit('toggle-Favorite');
  }
}

我们可以选择自定义事件的名称,但通常使用 kebab-case 来发出事件。


接收发出事件

自定义发出事件“toggle-favorite”现在从FoodItem.vue组件,但我们需要监听中的事件App.vue父级并调用一个执行某些操作的方法,以便我们可以看到事件发生了。

我们用简写来听事件@代替v-on:App.vue创建组件的位置:

示例

收听“切换最爱”事件App.vue:

<food-item
  v-for="x in foods"
  :key="x.name"
  :food-name="x.name"
  :food-desc="x.desc"
  :is-favorite="x.favorite"
  @toggle-favorite="receiveEmit"
/>

当我们的自定义“toggle-favorite”事件发生时,我们需要在中创建“testEmit”方法App.vue这样我们就可以看到事件发生了:

methods: {
  receiveEmit() {
    alert('Hello World!');
  }
}
运行示例 »

更改父级中食品项目的“最喜欢”状态

我们现在有一个事件通知App.vue当从子组件中单击“收藏夹”按钮时。

我们想要更改“foods”数组中的“favorite”属性App.vue单击“收藏夹”按钮后即可找到正确的食物。为此,我们发送食品名称FoodItem.vueApp.vue因为每种食品都是独一无二的:

FoodItem.vue:

methods: {
  toggleFavorite() {
    this.$emit('toggle-favorite', this.foodName);
  }
}

我们现在可以接收食品名称App.vue作为“toggle-favorite”事件发生时调用的方法的参数,如下所示:

示例

App.vue:

methods: {
  receiveEmit(foodId) {  
    alert( 'You clicked: ' + foodId );
  }
}
运行示例 »

现在我们知道点击了哪些食物,我们可以更新“foods”数组中正确食物的“最爱”状态:

App.vue:

methods: {
  receiveEmit(foodId) {
    const foundFood = this.foods.find(
      food => food.name === foodId
    );
    foundFood.favorite = !foundFood.favorite;
  }
}

在上面的代码中,数组方法“find”遍历“foods”数组,查找 name 属性等于我们单击的食物项的对象,并将该对象作为“foundFood”返回。之后,我们可以将“foundFood.health”设置为与之前相反,以便它在之间切换truefalse

了解有关 JavaScript 数组方法“find”的更多信息这里

了解有关 JavaScript 箭头函数的更多信息这里

“食物”数组中的正确食物现在会更新其“最喜欢的”状态。剩下的唯一一件事就是更新指示最喜欢的食物的图片。

因为食物项组件已经使用“foods”数组中的“favorite”状态创建,并作为 prop“is-favorite”发送App.vue,我们只需要在中引用这个 'isFavorite' 属性FoodItem.vuev-show哪里的<img>元素是更新图片:

<img src="/img_quality.svg" v-show="isFavorite">

我们还可以删除 'foodIsFavorite' 数据属性FoodItem.vue因为它不再使用了。

示例

在最后的示例代码中,可以按照与以前类似的方式切换食物的最喜欢状态,但现在最喜欢的状态在正确的位置进行了修改,即内部App.vue

运行示例 »

“发出”选项

就像我们在里面声明 props 一样FoodItem.vue组件,我们还可以使用 Vue 的“emits”选项来记录组件发出的内容。

props 必须在组件中声明,而emits 则建议记录下来。

这就是我们如何记录我们的发射FoodItem.vue成分:

<script>
export default {  
  props: ['foodName','foodDesc','isFavorite'],
  emits: ['toggle-favorite'],
  methods: {
    toggleFavorite() {
      this.$emit('toggle-favorite', this.foodName);
    }
  }
};
</script>

当发出被记录下来时,该组件将变得更容易被其他人使用。


Vue练习

通过练习测试一下

练习:

Props are used to send data 
from the parent element to the child component, 
and  is used to to pass information 
from the child component to the parent.

开始练习