在vue.js中放置事件处理程序?

时间:2019-06-26 00:30:41

标签: javascript vuejs2 vuetify.js

我正在尝试找出某些问题,并且遇到了问题。我有一些图标数据是从数组中的数组接收的,我只想在一个图标上放一个事件处理程序。例如,假设将事件处理程序放在“竖起大拇指”图标上以隐藏段落(类似这样)。

我已经制作了一个代码笔进行演示:https://codepen.io/anon/pen/gNxdER

<div id="app">
  <v-app id="inspire">
    <v-container>
      <v-data-table
        v-model="selected"
        :headers="headers"
        :items="desserts"
        item-key="name"
      >
        <template v-slot:items="props">
          <td>{{ props.item.name }}</td>
          <td>{{ props.item.calories }}</td>
          <td>{{ props.item.iron }}</td>
          <td><v-icon v-for="icon in props.item.icons">{{icon}}</v-icon></td>
        </template>
      </v-data-table>
    </v-container>
  </v-app>
</div>
new Vue({
  el: '#app',
  data () {
    return {
      headers: [
        {
          text: 'Dessert (100g serving)',
          align: 'left',
          sortable: false,
          value: 'name'
        },
        { text: 'Calories', value: 'calories' },
        { text: 'Iron (%)', value: 'iron' },
        { text: 'Icons', value: 'icon'}
      ],
      desserts: [
        {
          name: 'Frozen Yogurt',
          calories: 159,
          iron: '1%',
          icons: [
            'search',
            'dashboard',
            'timeline',
            'thumb_up'
          ]
        },
        {
          name: 'Ice cream sandwich',
          calories: 237,
          iron: '1%',
          icons: [
            'search',
            'dashboard',
            'timeline',
            'thumb_up'
          ]
        },
        {
          name: 'Eclair',
          calories: 262,
          iron: '7%',
          icons: [
            'search',
            'dashboard',
            'timeline',
            'thumb_up'
          ]
        },
        {
          name: 'Cupcake',
          calories: 305,
          iron: '8%',
          icons: [
            'search',
            'dashboard',
            'timeline',
            'thumb_up'
          ]
        }
      ]
    }
  }
})

谢谢您的帮助。

2 个答案:

答案 0 :(得分:2)

在v-for之后附加一个click事件,该事件将调用一个方法,您将该方法传递给该方法。

<v-icon v-for="icon in props.item.icons" @click="iconAction(item, icon)">{{icon}}</v-icon>

在您的方法中,您可以根据单击的项目对项目执行操作。

methods: {
  iconAction (item, icon){
    if (icon === 'thumbs_up') {
      // do somthing for thumbs_up
    } else if (icon === 'dashboard') {
      // do somthing for dashboard
    }
    ...
  }
}

答案 1 :(得分:2)

您可以使用v-on做这样的事情:

<v-icon v-for="icon in props.item.icons" v-on="getIconHandlers(icon)">{{icon}}</v-icon>

具有:

getIconHandlers (icon) {
  if (icon === 'thumb_up') {
    return {click: this.thumbUpClickHandler}
  }

  return null
}

当然,您还必须定义函数thumbUpClickHandler。您更可能希望将当前行的某些上下文传递给单击处理程序,这可以通过将这些额外的信息传递给getIconHandlers并在侦听器的结尾处捕获来实现:

getIconHandlers (icon, otherStuff /* <- pass whatever you need */) {
  if (icon === 'thumb_up') {
    return {
      click: () => {
        this.thumbUpClickHandler(otherStuff)
      }
    }
  }

  return null
}

可以在模板中内联所有这些操作,但是我认为将其拉出到单独的方法更容易理解。

这利用了v-on支持的对象语法,与v-bind非常相似。记录在https://vuejs.org/v2/api/#v-on中。使用属性键作为事件名称并将属性值用作相应的侦听器功能,将该对象的属性注册为侦听器。对于其他图标,我只返回null,尽管您也可以返回一个空对象。

Vuetify将为具有click侦听器的图标显示不同的鼠标光标,并且这样做只会改变thumb_up图标的光标,我认为这是这里的意图。

更新

由于仅需要一个事件,因此也可以使用v-on / @的方括号表达式语法来执行此操作。例如

@[getEventName(icon)]="onThumbIconClick"

这里getEventName将是诸如以下方法:

getEventName (icon) {
  return icon === 'thumb_up' ? 'click' : null
}

v-on内部有特殊处理,可确保在表达式计算为null时不注册任何侦听器。

我个人更喜欢前面描述的对象语法,但是出于完整性考虑,我认为值得一提。