vuejs官网之自定义事件

事件名

跟组件和prop不同,事件名不存在自动化的大小写转换,而是触发的事件名需要完全匹配监听这个事件所有的名称。举个例子,如果触发了一个camelcase名字的事件

this.$emit('myevent')

则监听这个名字的kebab-case的版本是不会有任何特效的

<my-component v-on:my-event="dosomething">

跟组件和prop不同,事件名不会被用作一个javascript变量名或属性名,所以就没有理由使用camelcase或Pascalcase了,并且v-on事件监听器在dom模板中会被自动转化为全小写(因为html是大小写不敏感的)。所以v-on:myEvent将会变成v-on:myevent——导致myEvent不可能被监听到。

因此,我们推荐你使用kebab-case事件名

自定义组件的v-model

一个组件上的v-model默认会利用名为value的prop和名为input的事件,但是想单选框、复选框等类型的输入控件可能会将value特性用于不同的目的。model选项可以用来避免这样的冲突

vue.component('cccc',{

model:{

prop:'checked',

event:'change'

},

props:{

checked:boolean

},

template:

<input type='ccc'

v-bind:checked="checked"

v-on:change="$emit('change',$event.target.checked)">

})

现在在这个组件上使用v-model的时候

<cccc v-model="dddd">

这里的dddd的值会传入名为checked的prop。同时cccc触发一个change事件并附带一个新的值的时候,这个dddd的属性将会被更新

注意你仍然需要在组件的props选项里生命checked这个prop

将原生事件绑定到组件

你可能有很多次想要在一个组件的根元素上直接监听一个原生事件。这是,你可以使用v-on的.native修饰符

<base-input v-on:focus.native="onfocus">

在有的时候这是很有用的,不过在你尝试监听一个<input>的非常特定的元素时,这并不是好主意,比如上述<base-input>组件可能做了如下重构,所有根元素实际上是一个<label>元素

<label>

{{label}}

<input

v-bind="$attrs"

v-bind:value="value"

v-on:input="$emit('input',$event.target.value)">

</label>

这时,父级的.native监听器将静默失败,他不会产生任何报错,但是onfocus处理函数不会如你预期的被调用,

为了解决这个问题,vue提供了一个$listeners属性,他是一个对象,里面包含了作用在这个组件上的所有监听器,

{focus:function(event){}

input:function(value){}}

有了这个$listener属性,你就可以配合v-on=“$listener”将所以的事件监听器指向这个组件的某个特定的子元素。对于类似<input>的你希望他也可以配合v-model工作的组件来说,为这些监听器创建一个类似下述的inputlisteners的计算属性通常是非常有用的,

vue.component('ddd',{

inheritAttrs:false,

props:['label','value'],

computed:{

inputlisteners:function(){

var vm=this

将所有的对象合并为一个新对象

return object.assign({},

我们从父级添加所有的监听器

this.$listeners,

然后我们添加自定义监听器,或覆写一些监听器的行为)

}{

这里确保组件配合v-model工作

input,function(evnet){

vm.$emit('inout'.event.target.value)

}

}

}})

template:

<label>

{{ label }}

<input

v-bind="$attrs"

v-bind:value="value"

v-on="inputListeners"

>

</label>

`

})可以

现在<base-input>组件是一个完全透明的包裹器了,也就是说他可以完全像一个普通的<input>元素一样使用了,所以跟他相同的特性和监听器的都可以工作。

 

.sync修饰符

在有些情况下 ,我们可能需要对一个prop进行双向绑定,不幸的是,真正的双向绑定会带来维护上的问题,因为子组件可以修改父组件,且在父组件和子组件都没有明显的改动来源。

 

这也是为什么我们推荐以update:my-prop-name的模式触发事件取而代之。举个例子,在一个包含title prop的假设的组件中,我们可以用以下方法表达对其赋新值的意图;

this.$emit(‘update:title’,newtitle)

然后父组件可以监听那个事件并根据需要更新一个本地的数据属性。

<text-document

v-bind:title="doc.title"

v-on:update:title="doc.title=$event"></text-document>

为了方便起见,我们为这种模式提供了一个缩写,即.sync修饰符

当我们用一个对象同时设置多个prop的时候,也可以将这个.sync修饰符和v-bind配合使用

<text-document v-bind.sync="doc">

这样会把doc对象中的每一个属性都作为一个独立的prop传进去,然后各自添加用于更新的v-on监听器。

将v-bind.sync用在一个字面量的对象上,例如v-bind.sync="{title:doc.title}"是无法正常工作的,因为在解析一个像这样的复杂表达式的时候,有很多边缘情况需要考虑。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值