我们知道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.rgba
。App.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中推进组件通信方面的知识,我建议您给出 这篇文章阅读。