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 相关文章推荐
可以支持多中格式的JS键盘
May 02 Javascript
IE的fireEvent方法概述及应用
Feb 22 Javascript
基于JavaScript 声明全局变量的三种方式详解
May 07 Javascript
关于javascript event flow 的一个bug详解
Sep 17 Javascript
jquery原理以及学习技巧介绍
Nov 11 Javascript
JS闭包、作用域链、垃圾回收、内存泄露相关知识小结
May 16 Javascript
JavaScript Promise 用法
Jun 14 Javascript
JavaScript数据操作_浅谈原始值和引用值的操作本质
Aug 23 Javascript
angular2路由之routerLinkActive指令【推荐】
May 30 Javascript
微信小程序使用wxParse解析html的方法教程
Jul 06 Javascript
浅谈Vue3.0之前你必须知道的TypeScript实战技巧
Sep 11 Javascript
Vue.js获取手机系统型号、版本、浏览器类型的示例代码
May 10 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
用PHP读注册表
2006/10/09 PHP
如何使用PHP获取网络上文件
2006/10/09 PHP
php 智能404跳转代码,适合换域名没改变目录的网站
2010/06/04 PHP
Yii基于CActiveForm的Ajax数据验证用法示例
2016/07/14 PHP
PHP explode()函数用法讲解
2019/02/15 PHP
Flash+XML滚动新闻代码 无图片 附源码下载
2007/11/22 Javascript
根据邮箱的域名跳转到相应的登录页面的代码
2012/02/27 Javascript
.net,js捕捉文本框回车键事件的小例子(兼容多浏览器)
2013/03/11 Javascript
js对象内部访问this修饰的成员函数示例
2014/04/27 Javascript
jQuery中 DOM节点操作方法大全
2017/10/12 jQuery
原生JS上传大文件显示进度条 php上传文件代码
2020/03/27 Javascript
node.js将MongoDB数据同步到MySQL的步骤
2017/12/10 Javascript
video.js 实现视频只能后退不能快进的思路详解
2018/08/09 Javascript
Intellij IDEA搭建vue-cli项目的方法步骤
2018/10/20 Javascript
JavaScript 实现HTML DOM增删改查操作的常见方法详解
2020/01/04 Javascript
Vue路由 重定向和别名的区别说明
2020/09/09 Javascript
[59:08]Ti4 冒泡赛第二天 NEWBEE vs Titan 2
2014/07/15 DOTA
python实现RSA加密(解密)算法
2016/02/17 Python
python中input()与raw_input()的区别分析
2016/02/27 Python
Python计算字符宽度的方法
2016/06/14 Python
python中的set实现不重复的排序原理
2018/01/24 Python
python将excel转换为csv的代码方法总结
2019/07/03 Python
Django框架模型简单介绍与使用分析
2019/07/18 Python
CSS3 真的会替代 SCSS 吗
2021/03/09 HTML / CSS
计算机专业个人求职信范例
2013/09/23 职场文书
会计实习生自我鉴定
2013/12/12 职场文书
哈理工毕业生的求职信
2013/12/22 职场文书
车贷收入证明范本
2014/01/09 职场文书
事业单位请假制度
2014/01/13 职场文书
工会主席事迹材料
2014/06/03 职场文书
自我查摆剖析材料
2014/10/11 职场文书
党员三严三实对照检查材料
2014/10/13 职场文书
思想品德评语大全
2014/12/31 职场文书
故宫导游词
2015/01/31 职场文书
学生会自荐信
2019/05/16 职场文书
MySQL千万级数据表的优化实战记录
2021/08/04 MySQL