动态添加事件到我的自定义网格组件

时间:2017-01-26 05:47:00

标签: vuejs2 vue.js

<template>
  <tbody>
  <template v-for="(row,index) in datalist">
    <tr @click="rowevent != null?rowevent(row,this.$el):''" :class="index % 2 === 0?bodytrclass[0]:bodytrclass[1]">
      <td v-if="col.show" v-for="col in collist" @click="eventbus(row,$event)" @mouseover="eventbus(row,$event)">
        <template v-if="col.type">
          <component v-for="com in col.type" :is="com" :rowdata="row" :colname="col.colname"
                     :tdcbfun="col.cbfun"></component>
        </template>
        <template v-else>{{ row[col.colname] }}</template>
      </td>
    </tr>
  </template>
  </tbody>
</template>
```

现在是个问题

`<tr @click="rowevent != null?rowevent(row,this.$el):''" :class="index % 2 === 0?bodytrclass[0]:bodytrclass[1]">`

我如何通过数据(道具)添加事件?动态v-on? 我不想写@click @moverover @ .......

我想要这样......

```
props: {
  trevent: [{event:'click',eventfun:function (rowdata) {
    if(rowdata.age<10){  //@:click=eventfun(rowdata)
       alert('children')
    }
 }},{event:'mouseover',eventfun:function (rowdata) {
    if(rowdata.age<10){//@mouseover=eventfun(rowdata)
       tip('children')
    }
 }}]
}
```

另一个示例按钮组件

```
<template>
  <div>
    <button @click="eventbus" @mouseover="eventbus">{{options.btnname}}</button>
  </div>
</template>

methods: {
      eventbus: function (rowdata, event) {
        var eventname = event.type
        var eventpos = event.currentTarget.localName

        this.$root.$emit(eventpos + eventname, rowdata)
      }
    }

vm.$on('trclick',function(){
.......do something
})
```

如果有时发出不是$ on不要这样......这种解决方案就这样......

我也可以使用组件:但是javaer必须编写这么多组件 哦,如果

对不起我的英文..

终于可以写中文了
我们公司正在开发一个公共组件,刚开始做现在正在做表格的组件。 这个组件是通用的,想用在公司的不同的系统上,也是开源的。 麻烦大家帮看看现在如何可以根据传入的道具数据,动态添加事件到某个标签上? 我找不到办法动态添加V-上
想做的功能多一些还不想总让研发人员写动态的组件
我尽量将vue封装成jquery那种调用形式,大家都比较容易会。 其次是我现在在mainjs里把vue写好的组件暴露出来的窗口。$ grid = grid.vue然后在引入webpack打包好的js 然后直接使用请问还有其他更好的关于把vue做成组件在外部调用的例子吗? 还有如果我这种方式引用的话是否还能使用vue-router?最好给个例子 最近半个月狂看Vue在此感谢下尤大弄出这么好的东西! 借这里给大家拜个早年,祝各位在新的一年里身体健康,生活幸福! 英语不好麻烦各位了

2 个答案:

答案 0 :(得分:0)

在编译之后修改组件DOM的事件侦听器可能不是最好的概念。如果从Evan You(vuejs的创建者)here找到此引用:

  

我认为你正在用错误的假设接近这个。组件的模板是静态的,一旦定义,您就无法更改它。您需要表达模板内可能更改的部分。

可能recompile a component template Elfayer显示here,但它不会提高此问题的优势,因为必须为每个属性配置提供模板。对于一个事件属性,没问题,您需要两个模板。但是对于三个事件,你已经需要8个模板等等......

选项1:处理正常事件处理程序中的逻辑

使用执行动态事件侦听器的条件执行的普通事件处理程序。 在您的模板中,您可以替换

<template>
...
    <tr @click="rowevent != null?rowevent(row,this.$el):''" :class="index % ...
...
</template>

使用:

<template>
...
    <tr @click="tr_handler(row,this.$el)" :class="index % ...
...
</template>

然后使用tr_handler()方法检查是否有分配给某个属性的事件侦听器:

methods: { 
   //...
   tr_handler: function(row,e) {
      if (this.rowevent) {
         return this.rowevent(row, e)
      }
   }
   //...
}

这种方法提供了一个干净的结构,并保留了vuejs的字符串模板功能。

选项2:使用render()功能

可以使用render function动态渲染整个模板。此外,可以将事件侦听器应用于节点,如后一个链接中所述:

on: {
  '!click': this.doThisInCapturingMode,
  '~keyup': this.doThisOnce,
  `~!mouseover`: this.doThisOnceInCapturingMode
}

这两种方法都不能避免在模板中声明事件。 Here is some statement about this解释了如何在vue-world中完成任务。

  

由于您不必在JS中手动附加事件侦听器,因此您的   ViewModel代码可以是纯逻辑和DOM。这使得它更容易   测试

答案 1 :(得分:0)

一种可能的方法是使用特殊的propr ref并在mounted生命周期中添加事件监听器。由于它是手动添加的,您可能也想删除它,因此我会在beforeDestroy生命周期中添加它。

将ref设置为标记

<tr ref="my-tag" :class="index % 2 === 0?bodytrclass[0]:bodytrclass[1]">

在livecycles中添加和删除事件

mounted() {
    this.$refs['my-tag'].addEventListener(this.myEvent,() => {
         // Some logic..
    });
},
beforeDestroy() {
    this.$refs['my-tag'].addEventListener(this.myEvent,() => {
         // Some logic..
    });
}

这可能不是更好的方法,但可以做到这一点。