Vue 自定义事件简介

我们知道Vue可以听取您的元素上的事件,并在发生此类事件时启动特定函数。Vue.js还允许您听取 自定义事件,这是一种功能,其最重要的用例是允许儿童组件启动家长组件可以收听的事件。

我们在 Vue Template Syntax 文章中创建了一个简单的照片画廊组件。你可以在一排小图中点击任何照片,然后你点击的照片将在下面显示大尺寸。

照片画廊的母组件App.vue只需要从其子组件PhotoGallery.vue接收照片的平均RGB值,当照片被点击时。

讓我們開始吧!本教程會找到 Template Syntax 教程停留的地方。

App 设置

让我们使用此前文章的相同设置(/vuejs/vue-template-syntax/#app-setup)。

让我们写一些自定义事件代码

我们将使用一个名为快速平均颜色npm库(https://www.npmjs.com/package/fast-average-color),以获取特定照片的平均颜色值,将其导入到PhotoGallery.vue<script>部分的顶部。

1import from 'fast-average-color';

目前,我们的PhotoGallery.vue组件有一个方法,即highlight(),当您点击照片时会触发。

 1highlight() {
 2  event.target.id = "theater";
 3  this.theatrical = event.target.src;
 4  let eventIterator = event.target.parentNode;
 5  while (eventIterator.previousElementSibling != null) {
 6    eventIterator.previousElementSibling.getElementsByTagName('img')[0].id = "";
 7    eventIterator = eventIterator.previousElementSibling;
 8  }
 9  eventIterator = event.target.parentNode;
10  while (eventIterator.nextElementSibling != null) {
11    eventIterator.nextElementSibling.getElementsByTagName('img')[0].id = "";
12    eventIterator = eventIterator.nextElementSibling;
13  }
14}

此方法将点击的照片显示在小图像下方的大小。请注意,我们在整个方法中使用了event.target

通过浏览快速平均颜色文件,我们可以找到getColorAsync函数,该函数返回一个颜色对象,其中color.rgba是平均RGB值。

1const fac = new FastAverageColor();
2
3fac.getColorAsync(event.target)
4  .then(function(color) {
5  })
6  .catch(function(e) {
7    console.log(e);
8  });

最终,我们需要在App.vue中将背景颜色设置为color.rgbaApp.vue将有一个将color.rgba作为论点的方法。

1methods: {
2  setBackground(rgba) {
3    document.querySelector('body').style.backgroundColor = rgba;
4  }
5}

这应该看起来对你好!

看看App.vue的模板部分,这就是它现在的样子:

1<template>
2  <div id="app">
3    <PhotoGallery />
4  </div>
5</template>

App组件将不得不从PhotoGallery组件中收集一个事件,这是一个自定义的事件,假设该事件被称为剧院模式;当我们想在我们的组件中听到这样的事件时,语法就和常规事件一样。

现在我们需要以某种方式将值color.rgba发送到App.vue


每个Vue组件都有一个方法$emit。这个方法允许你触发一个事件,在我们的情况下称之为剧院模式。我们将在然后函数内调用this.$emit从我们发出的非同步呼叫到颜色库。

 1highlight() {
 2  event.target.id = "theater";
 3  this.theatrical = event.target.src;
 4  let eventIterator = event.target.parentNode;
 5  while (eventIterator.previousElementSibling != null) {
 6    eventIterator.previousElementSibling.getElementsByTagName('img')[0].id = "";
 7    eventIterator = eventIterator.previousElementSibling;
 8  }
 9  eventIterator = event.target.parentNode;
10  while (eventIterator.nextElementSibling != null) {
11    eventIterator.nextElementSibling.getElementsByTagName('img')[0].id = "";
12    eventIterator = eventIterator.nextElementSibling;
13  }
14  const fac = new FastAverageColor();
15  fac.getColorAsync(event.target)
16    .then(function(color) {
17    })
18    .catch(function(e) {
19      console.log(e);
20    });
21}

this.$emit 将事件名称作为第一个参数,并具有可选的其他参数,您可以传输数据. 我们将传输 color.rgba. 因此,我们的函数调用将看起来像 this.$emit('theater-mode', color.rgba)

 1highlight() {
 2  event.target.id = "theater";
 3  this.theatrical = event.target.src;
 4  let eventIterator = event.target.parentNode;
 5  while (eventIterator.previousElementSibling != null) {
 6    eventIterator.previousElementSibling.getElementsByTagName('img')[0].id = "";
 7    eventIterator = eventIterator.previousElementSibling;
 8  }
 9  eventIterator = event.target.parentNode;
10  while (eventIterator.nextElementSibling != null) {
11    eventIterator.nextElementSibling.getElementsByTagName('img')[0].id = "";
12    eventIterator = eventIterator.nextElementSibling;
13  }
14  const fac = new FastAverageColor();
15  fac.getColorAsync(event.target)
16    .then((color) => this.$emit('theater-mode', color.rgba))
17    .catch(function(e) {
18      console.log(e);
19    });
20}

这对你来说应该很好!让我们回头看看App.vue

 1[label App.vue]
 2<template>
 3  <div id="app">
 4    <PhotoGallery/>
 5  </div>
 6</template>
 7
 8<script>
 9import PhotoGallery from './components/PhotoGallery.vue'
10
11export default {
12  name: 'App',
13  components: {
14    PhotoGallery
15  },
16  methods: {
17    setBackground(rgba) {
18      document.querySelector('body').style.backgroundColor = rgba;
19    }
20  }
21}
22</script>
23
24<style>
25#app {
26  font-family: Avenir, Helvetica, Arial, sans-serif;
27  -webkit-font-smoothing: antialiased;
28  -moz-osx-font-smoothing: grayscale;
29  text-align: center;
30  color: #2c3e50;
31  margin-top: 60px;
32}
33</style>

我们已经讨论过,听到剧院模式事件看起来像v-on:剧院模式

所以,我们写下如下:

1<template>
2  <div id="app">
3    <PhotoGallery v-on:theater-mode="setBackground($event)"/>
4  </div>
5</template>

恭喜你!

您刚刚成功发布了自定义事件,从父母组件中听到它,并访问了该事件发出的值。 检查您的浏览器。

如果您有兴趣在Vue中推进组件通信方面的知识,我建议您给出 这篇文章阅读

Published At
Categories with 技术
Tagged with
comments powered by Disqus