vue 自定义事件
We know that Vue can listen to events on your elements and trigger specific functions to run when such events occur. Vue.js also allows you to listen for custom events, an ability which has its most important use case in allowing child components to fire off events that parent components can listen for.
我们知道,Vue可以侦听元素上的事件并触发特定功能以在此类事件发生时运行。 Vue.js还允许您侦听自定义事件 ,此功能在允许子组件触发父组件可以侦听的事件方面具有最重要的用例。
We created a simple photo gallery component in the Vue Template Syntax article. You could click any of the photos in a row of thumbnails and the photo you clicked would be displayed in a large size below. Now, what if we wanted the background of the entire page to be set to the average color of the photo being displayed? We could call this something like theater mode.
我们在Vue模板语法文章中创建了一个简单的相册组件。 您可以单击缩略图行中的任何照片,并且您单击的照片将在下面以大尺寸显示。 现在,如果我们希望将整个页面的背景设置为所显示照片的平均颜色,该怎么办? 我们可以称其为剧院模式 。
The power of custom events is that we can fairly easily do that. The parent component of the photo gallery, App.vue
, simply needs to receive the average RGB value of the photo from its child component, PhotoGallery.vue
, when the photo is clicked.
自定义事件的力量在于我们可以轻松地做到这一点。 图片库的父组件App.vue
只需单击照片,即可从其子组件PhotoGallery.vue
接收照片的平均RGB值。
Let’s get started. This tutorial picks up where the Template Syntax tutorial left off.
让我们开始吧。 本教程介绍了模板语法教程的上一步。
应用程式设定 (App Setup)
Let’s use the same setup from this previous post.
让我们写一些自定义事件代码 (Let’s Write Some Custom Event Code)
We’re going to use an npm
library called fast-average-color
to get the average color value for a particular photo. Import it at the top of the <script>
section of PhotoGallery.vue
.
我们将使用一个称为fast-average-color
的npm
库来获取特定照片的平均颜色值。 将其导入到PhotoGallery.vue
的<script>
部分的顶部。
import from 'fast-average-color';
Our PhotoGallery.vue
component, currently, has a method, highlight()
, which is triggered when you click on one of the photos.
当前,我们的PhotoGallery.vue
组件具有方法highlight()
,当您单击其中一张照片时会触发该方法。
highlight() {
event.target.id = "theater";
this.theatrical = event.target.src;
let eventIterator = event.target.parentNode;
while (eventIterator.previousElementSibling != null) {
eventIterator.previousElementSibling.getElementsByTagName('img')[0].id = "";
eventIterator = eventIterator.previousElementSibling;
}
eventIterator = event.target.parentNode;
while (eventIterator.nextElementSibling != null) {
eventIterator.nextElementSibling.getElementsByTagName('img')[0].id = "";
eventIterator = eventIterator.nextElementSibling;
}
}
This method displays the clicked photo in a larger size below the thumbnails. Notice that we used event.target
all over the method. event.target
is the element that was clicked on. This is the image that we want to get the average color of.
此方法在缩略图下方以较大的尺寸显示单击的照片。 注意,我们在整个方法中都使用了event.target
。 event.target
是被单击的元素。 这是我们想要获得其平均颜色的图像。
By perusing the fast-average-color
docs, we can find the getColorAsync
function, which returns a color object where color.rgba
is the average RGB value. Let’s go ahead and make that function call.
通过仔细阅读fast-average-color
文档,我们可以找到getColorAsync
函数,该函数返回一个颜色对象,其中color.rgba
是平均RGB值。 让我们继续进行该函数调用。
const fac = new FastAverageColor();
fac.getColorAsync(event.target)
.then(function(color) {
})
.catch(function(e) {
console.log(e);
});
We’re not yet doing anything with color
. Ultimately, we need to set the background color to color.rgba
in App.vue
. App.vue
is going to have a method that takes color.rgba
as an argument. Why don’t we just go ahead and write that method?
我们尚未对color
进行任何处理。 最后,我们需要将背景色设置为color.rgba
在App.vue
。 App.vue
将具有一个将color.rgba
作为参数的方法。 我们为什么不继续写那个方法呢?
methods: {
setBackground(rgba) {
document.querySelector('body').style.backgroundColor = rgba;
}
}
That should look good to you!
那对您来说应该看起来不错!
Take a look at the template section of App.vue
. Here’s how it looks right now:
看一下App.vue
的模板部分。 现在的样子如下:
<template>
<div id="app">
<PhotoGallery />
</div>
</template>
The App
component is going to have to pick up an event from the PhotoGallery
component, a custom event. Say the event was called theater-mode
; when we want to listen for such an event in our component, the syntax is just like for regular events. That is, it would be: v-on:theater-mode
. When theater-mode
occurs we’ll call our setBackground
method.
App
组件将不得不从PhotoGallery
组件中拾取一个自定义事件。 假设该事件称为theater-mode
; 当我们想在组件中侦听此类事件时,其语法就像常规事件一样。 也就是说,它将是: v-on:theater-mode
。 当发生theater-mode
时,我们将调用setBackground
方法。
Now we need to send the value color.rgba
to App.vue
somehow. Go back to PhotoGallery.vue
.
现在,我们需要以某种方式将值color.rgba
发送到App.vue
。 返回到PhotoGallery.vue
。
Every Vue component has a method $emit
. This method allows you to trigger an event, in our case one called theater-mode
. We’re going to call this.$emit
inside the then
function from the async call we made to the color library. Let’s jog your memory.
每个Vue组件都有一个方法$emit
。 这种方法允许您触发一个事件,在我们的例子中称为theater-mode
。 我们将在对颜色库的异步调用中的then
函数中调用this.$emit
。 让我们慢跑您的记忆。
highlight() {
event.target.id = "theater";
this.theatrical = event.target.src;
let eventIterator = event.target.parentNode;
while (eventIterator.previousElementSibling != null) {
eventIterator.previousElementSibling.getElementsByTagName('img')[0].id = "";
eventIterator = eventIterator.previousElementSibling;
}
eventIterator = event.target.parentNode;
while (eventIterator.nextElementSibling != null) {
eventIterator.nextElementSibling.getElementsByTagName('img')[0].id = "";
eventIterator = eventIterator.nextElementSibling;
}
const fac = new FastAverageColor();
fac.getColorAsync(event.target)
.then(function(color) {
})
.catch(function(e) {
console.log(e);
});
}
this.$emit
takes the event name as its first argument and has optional further arguments in which you can pass data. We’ll pass color.rgba
. So our function call is going to look like this.$emit('theater-mode', color.rgba)
. Here’s our new function:
this.$emit
将事件名称作为其第一个参数,并具有其他可选参数,您可以在其中传递数据。 我们将传递color.rgba
。 所以我们的函数调用看起来像this.$emit('theater-mode', color.rgba)
。 这是我们的新功能:
highlight() {
event.target.id = "theater";
this.theatrical = event.target.src;
let eventIterator = event.target.parentNode;
while (eventIterator.previousElementSibling != null) {
eventIterator.previousElementSibling.getElementsByTagName('img')[0].id = "";
eventIterator = eventIterator.previousElementSibling;
}
eventIterator = event.target.parentNode;
while (eventIterator.nextElementSibling != null) {
eventIterator.nextElementSibling.getElementsByTagName('img')[0].id = "";
eventIterator = eventIterator.nextElementSibling;
}
const fac = new FastAverageColor();
fac.getColorAsync(event.target)
.then((color) => this.$emit('theater-mode', color.rgba))
.catch(function(e) {
console.log(e);
});
}
That should look good to you! Let’s look back at App.vue
.
那对您来说应该看起来不错! 让我们回顾一下App.vue
。
<template>
<div id="app">
<PhotoGallery/>
</div>
</template>
<script>
import PhotoGallery from './components/PhotoGallery.vue'
export default {
name: 'App',
components: {
PhotoGallery
},
methods: {
setBackground(rgba) {
document.querySelector('body').style.backgroundColor = rgba;
}
}
}
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
We already discussed that listening to the theater-mode
event looks like v-on:theater-mode
. When we listen for a custom event, we can access any data that is passed with it via $event
.
我们已经讨论过,收听theater-mode
事件的过程类似于v-on:theater-mode
。 侦听自定义事件时,我们可以访问通过$event
传递的任何数据。
So, we write the following:
因此,我们编写以下代码:
<template>
<div id="app">
<PhotoGallery v-on:theater-mode="setBackground($event)"/>
</div>
</template>
恭喜你! (Congratulations!)
You just successfully emitted a custom event, listened to it from a parent component and accessed the value emitted from the event. Check your browser. Your app should be working just as we intended it to. Good job and bon voyage! 🚢
您刚刚成功发出了一个自定义事件,从父组件侦听了该事件,并访问了该事件发出的值。 检查您的浏览器。 您的应用程序应能按预期运行。 干得好,一路顺风! 🚢
If you’re interested in furthering your knowledge around component communication in Vue, I recommend you give this article a read.
如果您有兴趣进一步了解Vue中的组件通信知识,建议您阅读本文 。
翻译自: https://www.digitalocean.com/community/tutorials/vuejs-vue-custom-events
vue 自定义事件