Vue自定义事件(详解)


Posted in Javascript onAugust 19, 2017

前面的话

父组件使用props传递数据给子组件,子组件怎么跟父组件通信呢?这时,Vue的自定义事件就派上用场了。本文将详细介绍Vue自定义事件

事件绑定

每个 Vue 实例都实现了事件接口 (Events interface),即

使用 $on(eventName) 监听事件
使用 $emit(eventName) 触发事件

[注意]Vue 的事件系统分离自浏览器的EventTarget API。尽管它们的运行类似,但是 $on 和 $emit 不是addEventListener 和 dispatchEvent 的别名

另外,父组件可以在使用子组件的地方直接用 v-on 来监听子组件触发的事件

[注意]不能用 $on 侦听子组件抛出的事件,而必须在模板里直接用 v-on 绑定

<div id="example">
 <parent></parent>
</div>
<script>
var childNode = {
 template: `<button @click="incrementCounter">{{ counter }}</button>`,
 data(){
  return {
   counter: 0
  }
 },
 methods:{
  incrementCounter(){
   this.counter ++;
   this.$emit('increment');
  }
 },
}
var parentNode = {
 template: `
 <div class="parent">
  <p>{{total}}</p>
  <child @increment="incrementTotal"></child>
  <child @increment="incrementTotal"></child>
 </div>
 `,
 components: {
  'child': childNode
 },
 data(){
  return {
   'total':0
  }
 },
 methods:{
  incrementTotal(){
   this.total ++;
  }
 }
};
// 创建根实例
new Vue({
 el: '#example',
 components: {
  'parent': parentNode
 }
})
</script>

命名约定

自定义事件的命名约定与组件注册及props的命名约定都不相同,由于自定义事件实质上也是属于HTML的属性,所以其在HTML模板中,最好使用中划线形式

<child @pass-data="getData"></child>

而子组件中触发事件时,同样使用中划线形式

this.$emit('pass-data',this.childMsg)

数据传递

子组件通过$emit可以触发事件,第一个参数为要触发的事件,第二个事件为要传递的数据

this.$emit('pass-data',this.childMsg)

父组件通过$on监听事件,事件处理函数的参数则为接收的数据

getData(value){
   this.msg = value;
}
<div id="example">
 <parent></parent>
</div>
<script>
var childNode = {
 template: `
 <div class="child">
  <div>
   <span>子组件数据</span>
   <input v-model="childMsg" @input="data">
  </div>
  <p>{{childMsg}}</p>
 </div>
 `,
 data(){
  return{
   childMsg:''
  }
 },
 methods:{
  data(){
   this.$emit('pass-data',this.childMsg)
  }
 }
}
var parentNode = {
 template: `
 <div class="parent">
  <div>
   <span>父组件数据</span>
   <input v-model="msg">
  </div>
  <p>{{msg}}</p>
  <child @pass-data="getData"></child>
 </div>
 `,
 components: {
  'child': childNode
 },
 data(){
  return {
   'msg':'match'
  }
 },
 methods:{
  getData(value){
   this.msg = value;
  }
 }
};
// 创建根实例
new Vue({
 el: '#example',
 components: {
  'parent': parentNode
 }
})
</script>

sync修饰符

在一些情况下,可能会需要对一个 prop 进行双向绑定。事实上,这正是Vue1.x中的 .sync修饰符所提供的功能。当一个子组件改变了一个 prop 的值时,这个变化也会同步到父组件中所绑定的值。这很方便,但也会导致问题,因为它破坏了单向数据流的假设。由于子组件改变 prop 的代码和普通的状态改动代码毫无区别,当光看子组件的代码时,完全不知道它何时悄悄地改变了父组件的状态。这在 debug 复杂结构的应用时会带来很高的维护成本,上面所说的正是在 2.0 中移除 .sync 的理由

从 2.3.0 起重新引入了 .sync 修饰符,但是这次它只是作为一个编译时的语法糖存在。它会被扩展为一个自动更新父组件属性的 v-on 侦听器

<comp :foo.sync="bar"></comp>

会被扩展为:

<comp :foo="bar" @update:foo="val => bar = val"></comp>

当子组件需要更新 foo 的值时,它需要显式地触发一个更新事件:

this.$emit('update:foo', newValue)

因此,可以使用.sync来简化自定义事件的操作,实现子组件向父组件的数据传递

<div id="example">
 <parent></parent>
</div>
<script src="https://unpkg.com/vue"></script>
<script>
var childNode = {
 template: `
 <div class="child">
  <div>子组件数据:{{childMsg}}</div>
  <input v-model="childMsg">
  <button @click=add >+1</button>
 </div>
 `,
 data(){
  return{
   childMsg: 0
  }
 },
 methods:{
  add(){
   this.childMsg++;
   this.$emit('update:foo',this.childMsg);
  }
 }
};
var parentNode = {
 template: `
 <div class="parent">
  <p>父组件数据:{{msg}}</p>
  <child :foo.sync="msg"></child>
 </div>
 `,
 components: {
  'child': childNode
 },
 data(){
  return {
   'msg':0
  }
 }
};
// 创建根实例
new Vue({
 el: '#example',
 components: {
  'parent': parentNode
 }
})
</script>

以上这篇Vue自定义事件(详解)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
JSON JQUERY模板实现说明
Jul 03 Javascript
Javascript面向对象扩展库代码分享
Mar 27 Javascript
JavaScript的Module模式编程深入分析
Aug 13 Javascript
AngularJS解决ng界面长表达式(ui-set)的方法分析
Nov 07 Javascript
jQuery实现的动态文字变化输出效果示例【附演示与demo源码下载】
Mar 24 jQuery
vue-router 路由基础的详解
Oct 17 Javascript
基于jQuery中ajax的相关方法汇总(必看篇)
Nov 08 jQuery
Vue中的Vux配置指南
Dec 08 Javascript
angular4 共享服务在多个组件中数据通信的示例
Mar 30 Javascript
vue组件与复用详解
Apr 08 Javascript
微信小程序常用赋值方法小结
Apr 30 Javascript
Vue中登录验证成功后保存token,并每次请求携带并验证token操作
Sep 08 Javascript
Vue内容分发slot(全面解析)
Aug 19 #Javascript
简单的网页广告特效实例
Aug 19 #Javascript
JavaScript 完成注册页面表单校验的实例
Aug 19 #Javascript
JS模拟超市简易收银台小程序代码解析
Aug 18 #Javascript
详解JS数组Reduce()方法详解及高级技巧
Aug 18 #Javascript
javascript将url解析为json格式的两种方法
Aug 18 #Javascript
Vue组件选项props实例详解
Aug 18 #Javascript
You might like
骨王战斗力在公会成员中排不进前五,却当选了会长,原因竟是这样
2020/03/02 日漫
php foreach 使用&amp;(与运算符)引用赋值要注意的问题
2010/02/16 PHP
php将mysql数据库整库导出生成sql文件的具体实现
2014/01/08 PHP
PHP实现Redis单据锁以及防止并发重复写入
2018/04/10 PHP
JavaScript中的History历史对象
2008/01/16 Javascript
JavaScript读取中文cookie时的乱码问题的解决方法
2009/10/14 Javascript
js数据验证集合、js email验证、js url验证、js长度验证、js数字验证等简单封装
2010/05/15 Javascript
基于JQuery的多标签实现代码
2012/09/19 Javascript
js中function()使用方法
2013/12/24 Javascript
详解Bootstrap按钮
2016/01/04 Javascript
给angular加上动画效遇到的问题总结
2016/02/17 Javascript
在AngularJS框架中处理数据建模的方式解析
2016/03/05 Javascript
基于JavaScript实现快速转换文本语言(繁体中文和简体中文)
2016/03/07 Javascript
Javascript数组循环遍历之forEach详解
2016/11/07 Javascript
详解vue数据渲染出现闪烁问题
2017/06/29 Javascript
基于Node.js实现压缩和解压缩的方法
2018/02/13 Javascript
Javascript Promise用法详解
2018/05/10 Javascript
angular2路由之routerLinkActive指令【推荐】
2018/05/30 Javascript
JavaScript学习笔记之图片库案例分析
2019/01/08 Javascript
vue 使用element-ui中的Notification自定义按钮并实现关闭功能及如何处理多个通知
2019/08/17 Javascript
小程序使用wxs解决wxml保留2位小数问题
2019/12/13 Javascript
[01:12](回顾)DOTA2国际邀请赛,全世界DOTAer的盛宴
2014/07/01 DOTA
在Python3中初学者应会的一些基本的提升效率的小技巧
2015/03/31 Python
使用python telnetlib批量备份交换机配置的方法
2019/07/25 Python
Python3标准库之threading进程中管理并发操作方法
2020/03/30 Python
如何用H5实现一个触屏版的轮播器的实例
2017/01/09 HTML / CSS
夏尔巴人登珠峰品牌:Sherpa Adventure Gear
2018/02/08 全球购物
西班牙土拨鼠床垫公司,感觉在云端:Marmota
2019/03/18 全球购物
伦敦最受欢迎的蛋糕店:Konditor & Cook
2019/11/01 全球购物
超市营业员求职简历的自我评价
2013/10/17 职场文书
心得体会开头
2014/01/01 职场文书
致跳远运动员广播稿
2014/02/11 职场文书
《鹬蚌相争》教学反思
2014/04/22 职场文书
《田忌赛马》教学反思
2016/02/19 职场文书
Java异常体系非正常停止和分类
2022/06/14 Java/Android
nginx七层负载均衡配置详解
2022/07/15 Servers