自定义事件在 Vue.js 组件中的应用
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了自定义事件在 Vue.js 组件中的应用相关的知识,希望对你有一定的参考价值。
编辑
Vue.js 组件的自定义事件可以让子组件向父组件传递数据,非常方便实用。在使用自定义事件时,我们可以使用 v-on 来绑定事件,每个 Vue 实例都实现了事件接口,即使用 $on(eventName) 监听事件和使用 $emit(eventName) 触发事件。此外,在父组件中,我们可以使用 v-on 来监听子组件触发的事件。
下面是一个示例,子组件和它外部完全解耦,只需要触发一个父组件关心的内部事件:
Copy
<div id="app">
<div id="counter-event-example">
<p> total </p>
<button-counter v-on:increment="incrementTotal"></button-counter>
<button-counter v-on:increment="incrementTotal"></button-counter>
</div>
</div>
Copy
Vue.component(button-counter,
template: <button v-on:click="incrementHandler"> counter </button>,
data()
return
counter: 0,
;
,
methods:
incrementHandler()
this.counter += 1;
this.$emit(increment);
,
,
);
new Vue(
el: #counter-event-example,
data:
total: 0,
,
methods:
incrementTotal()
this.total += 1;
,
,
);
如果要监听某个组件的根元素上的原生事件,可以使用 .native 修饰 v-on。
另外,组件上的 v-model 默认会利用名为 value 的 prop 和名为 input 的事件,可以通过 model 选项指定当前的事件类型和传入的 props。
以下是一个示例,父组件的 num 的初始值是 100,更改子组件的值能实时更新父组件的 num:
Copy
<div id="app">
<kxdang-input v-model="num"></kxdang-input>
<p>输入的数字为:num</p>
</div>
Copy
Vue.component(kxdang-input,
template: `
<p>
<input
ref="input"
:value="value"
@input="$emit(input, $event.target.value)"
>
</p>
`,
props: [value],
);
new Vue(
el: #app,
data:
num: 100,
,
);
总的来说,Vue.js 组件的自定义事件和 v-model 机制非常强大,能够让我们更加方便地进行组件间的数据交互。需要注意的是,在使用自定义事件时,我们应该避免出现命名冲突,以免产生不必要的错误。同时,在使用 v-model 时,我们也要注意传入的 props 和事件名的对应关系。
Vue.js 自定义事件命名
【中文标题】Vue.js 自定义事件命名【英文标题】:Vue.js custom event naming 【发布时间】:2017-07-15 11:32:43 【问题描述】:我有两个组件,一个包含另一个。
当我从孩子触发事件时,我无法在父母那里收到它。
子组件
this.$emit('myCustomEvent', this.data);
父组件
<parent-component v-on:myCustomEvent="doSomething"></parent-component>
但是,当我在两个地方都将事件名称更改为 my-custom-event 时,它可以正常工作。
Vue 以某种方式转换事件名称?或者可能是什么问题? 我阅读了docs 关于组件命名约定的内容,但没有与事件命名相关的内容
【问题讨论】:
【参考方案1】:Vue.js 不仅会转换 xml 标签(组件名称),还会转换属性,所以当您生成事件时
$emit('iLikeThis')
您必须将其处理为:
v-on:i-like-this="doSomething"
来自文档:
注册组件(或props)时,可以使用kebab-case, camelCase 或 TitleCase。 ...
不过,在 HTML 模板中,您必须使用 kebab-case 等价物:
【讨论】:
不工作。 Vue 不会将 camelCase 转换为 kebab ...但是如果我以 kebab 样式发出事件并以 kebab 样式收听它,它就可以工作。 same here.. 这似乎不适用于事件(不再)。使用 v2.4.2 这不是一个wiki,而是一个问题的答案,它是有效且正确的。将文档用于...新功能 @ssc-hrep3 的文档。 这里有一个文档链接,明确指出上述内容不起作用:vuejs.org/v2/guide/components-custom-events.html#Event-Names 这不适用于自定义事件命名【参考方案2】:对于自定义事件,最安全的选择是只使用一个小写的事件名称,所有这些事件名称都拼在一起。目前,即使是 kebab-case 也会有问题。
this.$emit('mycustomevent', this.data);
然后,在父组件中,随意绑定到驼峰式函数
<parent-component v-on:mycustomevent="doSomething"></parent-component>
它有点笨拙,但它有效。
Source(表示 kebab-case 也不起作用)
【讨论】:
v2 指南也有解释:vuejs.org/v2/guide/components-custom-events.html#Event-Names 链接问题指出 mixing 骆驼案例与 kebab-case 不起作用。 Kebab-case 本身this.$emit('my-event', this.data);
和 v-on:my-event="doSomething"
工作得很好。【参考方案3】:
建议始终使用kebab-case
来命名自定义事件。 小写事件,按照@KoriJohnRoys 的建议,全部拼凑在一起也可以,但更难阅读。事件命名不建议使用camelCase
。
official documentation of Vue.JS 在事件名称主题下声明如下:
事件名称
与组件和道具不同,事件名称不提供任何自动大小写转换。相反,发出事件的名称必须与用于侦听该事件的名称完全匹配。例如,如果发出驼峰式事件名称:
this.$emit('myEvent')
听 kebab-cased 版本没有效果:
<my-component v-on:my-event="doSomething"></my-component>
与组件和道具不同,事件名称永远不会用作 JavaScript 中的变量或属性名称,因此没有理由使用 camelCase 或 PascalCase。此外,DOM 模板中的 v-on 事件侦听器将自动转换为小写(由于 HTML 不区分大小写),因此 v-on:myEvent 将变为 v-on:myevent - 使 myEvent 无法侦听。
出于这些原因,我们建议您始终使用 kebab-case 作为事件名称。
【讨论】:
@Gjaa 我刚刚在 Vue 2.6.10 中重新测试了它,它的行为仍然相同。你可能在其他地方有问题。您能否在 *** 上提供更多信息或提出新问题? 我也必须使用 kebab case 发出我的事件才能使其工作,this.$emit('my-event')
。在我的$emit
上使用骆驼皮套不起作用:耸耸肩:
建议始终使用 kebab-case 来命名自定义事件。 使用 camelCase 将不起作用。【参考方案4】:
除了@ssc-hrep3关于kebab-case
的点
.sync 的文档建议使用 update:myPropName
模式
【讨论】:
以上是关于自定义事件在 Vue.js 组件中的应用的主要内容,如果未能解决你的问题,请参考以下文章
Vue:从自定义组件派生的自定义组件中的 v-model 和输入事件