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 相关文章推荐
jquery插件如何使用 jQuery操作Cookie插件使用介绍
Dec 15 Javascript
onkeydown事件解决按回车键直接提交数据的需求
Apr 11 Javascript
Enter转换为Tab的小例子(兼容IE,Firefox)
Nov 14 Javascript
深入理解JavaScript系列(19):求值策略(Evaluation strategy)详解
Mar 05 Javascript
jQuery插件实现带圆点的焦点图片轮播切换
Jan 18 Javascript
javascript特殊日历控件分享
Mar 07 Javascript
jQuery图片前后对比插件beforeAfter用法示例【附demo源码下载】
Sep 20 Javascript
js实现可旋转的立方体模型
Oct 16 Javascript
jQuery的Read()方法代替原生JS详解
Nov 08 Javascript
JavaScript获取服务器端时间的方法
Nov 29 Javascript
转换layUI的数据表格中的日期格式方法
Sep 19 Javascript
vue表单中遍历表单操作按钮的显示隐藏示例
Oct 30 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
广播爱好者需要了解的天线知识
2021/03/01 无线电
php过滤html标记属性类用法实例
2014/09/23 PHP
PHP的switch判断语句的“高级”用法详解
2014/10/01 PHP
分享php代码将360浏览器导出的favdb的sqlite数据库文件转换为html
2015/12/09 PHP
PHP将页面中点击数量高的链接进行高亮显示的方法
2016/05/30 PHP
PHP读取XML文件的方法实例总结【DOMDocument及simplexml方法】
2019/09/10 PHP
Yii框架 session 数据库存储操作方法示例
2019/11/18 PHP
html组件不可输入(只读)同时任何组件都有效
2013/04/01 Javascript
jQuery控制iFrame(实例代码)
2013/11/19 Javascript
js数组与字符串的相互转换方法
2014/07/09 Javascript
node.js中的fs.symlink方法使用说明
2014/12/15 Javascript
jQuery实现对无序列表的排序功能(附demo源码下载)
2016/06/25 Javascript
jQuery简单实现点击文本框复制内容到剪贴板上的方法
2016/08/01 Javascript
JavaScript将DOM事件处理程序封装为event.js 出现的低级错误问题
2016/08/03 Javascript
详解微信小程序开发—你期待的分享功能来了,微信小程序序新增5大功能
2016/12/23 Javascript
详解vue.js移动端导航navigationbar的封装
2017/07/05 Javascript
简易Vue评论框架的实现(父组件的实现)
2018/01/08 Javascript
vue select二级联动第二级默认选中第一个option值的实例
2018/01/10 Javascript
Angular实现的进度条功能示例
2018/02/18 Javascript
JS匿名函数和匿名自执行函数概念与用法分析
2018/03/16 Javascript
js数组去重的N种方法(小结)
2018/06/07 Javascript
Vue CLI3创建项目部署到Tomcat 使用ngrok映射到外网
2019/05/16 Javascript
详解ng-alain动态表单SF表单项设置必填和正则校验
2019/06/11 Javascript
小程序websocket心跳库(websocket-heartbeat-miniprogram)
2020/02/23 Javascript
使用Python进行新浪微博的mid和url互相转换实例(10进制和62进制互算)
2014/04/25 Python
利用标准库fractions模块让Python支持分数类型的方法详解
2017/08/11 Python
Python基于lxml模块解析html获取页面内所有叶子节点xpath路径功能示例
2018/05/16 Python
Python使用itertools模块实现排列组合功能示例
2018/07/02 Python
Python实现图片转字符画的代码实例
2019/02/22 Python
Python3使用xlrd、xlwt处理Excel方法数据
2020/02/28 Python
PyCharm取消波浪线、下划线和中划线的实现
2020/03/03 Python
Python Selenium实现无可视化界面过程解析
2020/08/25 Python
python一些性能分析的技巧
2020/08/30 Python
聘任通知书
2015/09/21 职场文书
2016年重阳节慰问信
2015/12/01 职场文书
html+css实现环绕倒影加载特效
2021/07/07 HTML / CSS