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当一个变量为函数时 应该注意的一点细节小结
Dec 29 Javascript
Javascript中Event属性搜集整理
Sep 17 Javascript
JS小功能(列表页面隔行变色)简单实现
Nov 28 Javascript
jQuery及JS实现循环中暂停的方法
Feb 02 Javascript
QQ登录背景闪动效果附效果演示源码下载
Sep 22 Javascript
Bootstrap如何创建表单
Oct 21 Javascript
AngularJS用户选择器指令实例分析
Nov 04 Javascript
详解vue事件对象、冒泡、阻止默认行为
Mar 20 Javascript
Angular获取手机验证码实现移动端登录注册功能
May 17 Javascript
基于vue2.0动态组件及render详解
Mar 17 Javascript
解决qrcode.js生成二维码时必须定义一个空div的问题
Jul 09 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
全国FM电台频率大全 - 13 福建省
2020/03/11 无线电
php FPDF类库应用实现代码
2009/03/20 PHP
PHP执行Curl时报错提示CURL ERROR: Recv failure: Connection reset by peer的解决方法
2014/06/26 PHP
php过滤HTML标签、属性等正则表达式汇总
2014/09/22 PHP
php微信公众开发之获取周边酒店信息的方法
2014/12/22 PHP
分享php邮件管理器源码
2016/01/06 PHP
PHP两种实现无级递归分类的方法
2017/03/02 PHP
PHP autoload使用方法及步骤详解
2020/09/05 PHP
js 实现菜单左右滚动显示示例介绍
2013/11/21 Javascript
jQuery UI插件自定义confirm确认框的方法
2015/03/20 Javascript
jQuery元素属性操作实例(设置、获取及删除元素属性)
2016/09/08 Javascript
jquery checkbox的相关操作总结
2016/10/17 Javascript
canvas实现钟表效果
2017/02/13 Javascript
微信小程序 setData的使用方法详解
2017/04/20 Javascript
JS回调函数基本定义与用法实例分析
2017/05/24 Javascript
angular 用拦截器统一处理http请求和响应的方法
2017/06/08 Javascript
手动下载Chrome并解决puppeteer无法使用问题
2018/11/12 Javascript
JavaScript获取某一天所在的星期
2019/09/05 Javascript
Python深入学习之上下文管理器
2014/08/31 Python
python用户管理系统的实例讲解
2017/12/23 Python
python编程实现随机生成多个椭圆实例代码
2018/01/03 Python
Python3实现转换Image图片格式
2018/06/21 Python
Python弹出输入框并获取输入值的实例
2019/06/18 Python
Python3如何在Windows和Linux上打包
2020/02/25 Python
最简单的matplotlib安装教程(小白)
2020/07/28 Python
pycharm配置python 设置pip安装源为豆瓣源
2021/02/05 Python
python爬取youtube视频的示例代码
2021/03/03 Python
美国最值得信赖的宠物药房:Allivet
2019/03/23 全球购物
硅酸盐工业控制专业应届生求职信
2013/11/02 职场文书
运动会通讯稿300字
2014/02/02 职场文书
班干部演讲稿
2014/04/24 职场文书
国际商贸专业自荐信
2014/06/09 职场文书
幼儿园母亲节活动总结
2015/02/10 职场文书
小学生2015教师节演讲稿
2015/03/19 职场文书
烈士陵园观后感
2015/06/08 职场文书
大学生暑期实践报告
2015/07/13 职场文书