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 相关文章推荐
Javascript this关键字使用分析
Oct 21 Javascript
jquery 双色表格实现代码
Dec 08 Javascript
JavaScript面向对象(极简主义法minimalist approach)
Jul 17 Javascript
JavaScript结合AJAX_stream实现流式显示
Jan 08 Javascript
关于JSON与JSONP简单总结
Aug 16 Javascript
Vue源码解析之Template转化为AST的实现方法
Dec 14 Javascript
微信小程序实现元素渐入渐出动画效果封装方法
May 18 Javascript
解决vue cli使用typescript后打包巨慢的问题
Sep 30 Javascript
浅谈vue中组件绑定事件时是否加.native
Nov 09 Javascript
JavaScript数值类型知识汇总
Nov 17 Javascript
jQuery 移除事件的方法
Jun 20 jQuery
最全vue的vue-amap使用高德地图插件画多边形范围的示例代码
Jul 17 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中多维数组的foreach遍历示例
2014/06/13 PHP
PHP生成二维码的两个方法和实例
2014/07/01 PHP
CodeIgniter连贯操作的底层原理分析
2016/05/17 PHP
ThinkPHP3.1.2 使用cli命令行模式运行的方法
2020/04/14 PHP
javascript 多级checkbox选择效果
2009/08/20 Javascript
jquery.hotkeys监听键盘按下事件keydown插件
2014/05/11 Javascript
jQuery拖拽插件gridster使用指南
2015/04/21 Javascript
JS实现仿QQ效果的三级竖向菜单
2015/09/25 Javascript
javascript html5移动端轻松实现文件上传
2020/03/27 Javascript
AngularJS基础 ng-options 指令详解
2016/08/02 Javascript
轮播图组件js代码
2016/08/08 Javascript
JS操作input标签属性checkbox全选的实现代码
2017/03/02 Javascript
js/jq仿window文件夹移动/剪切/复制等操作代码
2017/03/08 Javascript
基于JavaScript或jQuery实现网站夜间/高亮模式
2020/05/30 jQuery
解决vue单页面应用进入页面加载所有 js 的问题
2020/08/12 Javascript
VUE Elemen-ui之穿梭框使用方法详解
2021/01/19 Javascript
Python获取电脑硬件信息及状态的实现方法
2014/08/29 Python
在PyCharm导航区中打开多个Project的关闭方法
2019/01/17 Python
Python多线程处理实例详解【单进程/多进程】
2019/01/30 Python
pytorch 使用单个GPU与多个GPU进行训练与测试的方法
2019/08/19 Python
python实现网站微信登录的示例代码
2019/09/18 Python
Python利用多线程同步锁实现多窗口订票系统(推荐)
2019/12/22 Python
Tensorflow限制CPU个数实例
2020/02/06 Python
Python下划线5种含义代码实例解析
2020/07/10 Python
ivx平台开发之不用代码实现一个九宫格抽奖功能
2021/01/27 HTML / CSS
Hertz荷兰:荷兰和全球租车
2018/01/07 全球购物
Spartoo西班牙官网:法国时尚购物网站
2018/03/27 全球购物
波兰家居和花园家具专家:4Home
2019/05/26 全球购物
计算 s=(x*y)1/2,用两个宏定义来实现
2016/08/11 面试题
大学系主任推荐信范文
2013/12/24 职场文书
安全生产投入制度
2014/01/29 职场文书
小学优秀班主任材料
2014/12/17 职场文书
财政局长个人总结
2015/03/04 职场文书
学生会生活部工作总结2015
2015/03/31 职场文书
不知如何爱孩子,这些方法教会您
2019/08/06 职场文书
在Python 中将类对象序列化为JSON
2022/04/06 Python