在 Vue 组件中使用匿名函数作为事件处理程序 [英] Using anonymous function as an event handler in Vue component

查看:23
本文介绍了在 Vue 组件中使用匿名函数作为事件处理程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直环顾四周,发现我的问题最常见的解决方案是使用应用程序/组件的实例设置一个变量,然后使用该变量更改data(示例 1,示例 2).

我的问题是我不能使用箭头函数(我只被允许使用 ES5 兼容的 JS,而不是我的调用)并且我的函数没有前一个"部分来设置应用程序实例.

var theApp = new Vue({el: '#the-app',数据: {选择视图:1,myDynamicButtonsArray: [{text: '改变视图!!'onClick: 函数 () {//这里 this.selectedView 应该被改变this.selectedView = 2;}},{文本:'我的另一个按钮'onClick: 函数 () {//这里应该发生一些完全不相关的事情}}]}});

I 循环遍历 myDynamicButtonsArray 并加载一个 myButton 组件,该组件在单击时执行 onClick.

<my-button v-for="myDynamicButtonsArray 中的按钮" v-bind="button"></my-button>

问题是,当我执行 this.selectedView = 2; 时,this 不是指应用程序实例,而是执行它的函数实例,使得感觉.

我试过这样设置值:

theApp._data.selectedView = 2;

但我不确定这是否是正确的方法.

我不使用$emit的原因是因为有很多不同的函数要执行,并且发出一个button-clicked然后执行一个通用函数带有一个巨大的开关,因此它会根据按下的按钮做一件事或另一件事,这似乎不是一个可行的解决方案:

//MyButton 组件模板<button @onClick="this.$emit('button-clicked', id)">{{ 文本 }}//应用程序html<我的按钮v-for="myDynamicButtonsArray 中的按钮"v-bind="按钮"@button-clicked="buttonClicked"></我的按钮>//应用对象var theApp = new Vue({el: '#the-app',数据: {选择视图:1,myDynamicButtonsArray: [{text: '改变视图!!',编号:1},{text: '我的另一个按钮',编号:2}]},方法: {按钮点击:功能(ID){开关(ID){情况1:this.selectedView = 2;//我什至不确定我是否可以在这里按照我想要的方式使用this";休息;案例2://等等我所有的按钮}}}});

并且每个按钮发出不同的事件似乎也不可行:

//MyButton 组件模板<button @onClick="this.$emit(customEventString)">{{ 文本 }}//应用程序html<我的按钮v-for="myDynamicButtonsArray 中的按钮"v-bind="按钮"@custom-event-1="customEvent1"@custom-event-2="customEvent2"></我的按钮>//应用对象var theApp = new Vue({el: '#the-app',数据: {选择视图:1,myDynamicButtonsArray: [{text: '改变视图!!',customEventString: 'custom-event-1'},{text: '我的另一个按钮',customEventString: 'custom-event-2'}]},方法: {自定义事件1:函数(){this.selectedView = 2;//我什至不确定我是否可以在这里按照我想要的方式使用this";},customEvent2:函数(){//做其他事情}}});

我的问题是,哪种方法是正确的:

  • 使用 myApp._data
  • 里面有一个事件和一个switch
  • 或者别的东西

解决方案

首先,您需要从 data 属性返回一个函数,然后将 this 关键字绑定到功能

示例:

const MyButton = Vue.component('my-button', {模板:'<button v-text="text" @click="onClick"></button>',道具:['文本','onClick']});新的 Vue({el: '#the-app',组件:{ MyButton },数据:函数(){返回 {选择视图:1,纽扣: [{text: '改变视图!!',onClick: 函数 () {console.log('btn 1 单击')//这里 this.selectedView 应该被改变this.selectedView = 2;}.绑定(这个)},{text: '我的另一个按钮',onClick: 函数 () {console.log('btn 2 点击')//这里应该发生一些完全不相关的事情}}]}}});

{{ selectedView }}<my-button v-for="(button, index) in buttons" :key="index" v-bind="button"/>

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>

I have been looking around and found that the most common solution to my problem is to set a variable with the instance of the app/component and then using this variable to change the data (Example 1, Example 2).

My issue is that I cannot use arrow functions (I am only allowed to use ES5 comptible JS, not my call) and that my function does not have a "previous" part to set the app instance.

var theApp = new Vue({
    el: '#the-app',
    data: {
        selectedView: 1,
        myDynamicButtonsArray: [
            {
                text: 'Change view!!'
                onClick: function () {
                    // here this.selectedView should be changed
                    this.selectedView = 2;
                }
            },
            {
                text: 'My other button'
                onClick: function () {
                    // Here something completely unrelated should happen
                }
            }
        ]
    }
});

The I loop over myDynamicButtonsArray and load a myButton component that executes the onClick when clicked.

<my-button v-for="button in myDynamicButtonsArray" v-bind="button"></my-button>

The problem is that when I execute this.selectedView = 2; the this is not refering to the app instance but the function instance where it is being executed, makes sense.

I have tried setting the value like this:

theApp._data.selectedView = 2;

But I am not sure if this is the right approach.

The reason why I am not using the $emit is because there are many different functions to be executed, and emiting a button-clicked and then executing a common function with a giant switch so it does one thing or another depending on what button was pressed does not seem like a viable solution:

// MyButton component template
<button @onClick="this.$emit('button-clicked', id)">
    {{ text }}
</button>

// App html
<my-button 
    v-for="button in myDynamicButtonsArray" 
    v-bind="button"
    @button-clicked="buttonClicked"
>
</my-button>

// App object
var theApp = new Vue({
    el: '#the-app',
    data: {
        selectedView: 1,
        myDynamicButtonsArray: [
            {
                text: 'Change view!!',
                id: 1
            },
            {
                text: 'My other button',
                id: 2
            }
        ]
    },
    methods: {
        buttonClicked: function(id) {
            switch(id) {
                case 1:
                    this.selectedView = 2; 
                    // I am not even sure if I can use 'this' the way I want here;
                    break;
                case 2:
                    // And so on for all my buttons
            }
        }
    }
});

And emitting a different event per button does also not seem viable:

// MyButton component template
<button @onClick="this.$emit(customEventString)">
    {{ text }}
</button>

// App html
<my-button 
    v-for="button in myDynamicButtonsArray" 
    v-bind="button"
    @custom-event-1="customEvent1"
    @custom-event-2="customEvent2"
>
</my-button>

// App object
var theApp = new Vue({
    el: '#the-app',
    data: {
        selectedView: 1,
        myDynamicButtonsArray: [
            {
                text: 'Change view!!',
                customEventString: 'custom-event-1'
            },
            {
                text: 'My other button',
                customEventString: 'custom-event-2'
            }
        ]
    },
    methods: {
        customEvent1: function() {
            this.selectedView = 2; 
            // I am not even sure if I can use 'this' the way I want here;
        },
        customEvent2: function() {
            // Do other things
        }
    }
});

My question is, which is the right approach:

  • Using myApp._data
  • Having one event and a switch inside
  • Or something else

解决方案

First you need to return a function off your data property and second bind the this keyword to the function

Example:

const MyButton = Vue.component('my-button', {
  template: '<button v-text="text" @click="onClick"></button>',
  props: ['text', 'onClick']
});

new Vue({
  el: '#the-app',
    
  components: { MyButton },
  
  data: function() {
    return {
      selectedView: 1,
      buttons: [
        {
          text: 'Change view!!',
          onClick: function () {
            console.log('btn 1 clicked')
            // here this.selectedView should be changed
            this.selectedView = 2;
          }.bind(this)
        },
        {
          text: 'My other button',
          onClick: function () {
            console.log('btn 2 clicked')
            // Here something completely unrelated should happen
          }
        }
      ]
    }
  }
});

<div id="the-app">
  {{ selectedView }}
  <my-button v-for="(button, index) in buttons" :key="index" v-bind="button" />
</div>


<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>

这篇关于在 Vue 组件中使用匿名函数作为事件处理程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆