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 相关文章推荐
使用Firebug对js进行断点调试的图文方法
Apr 02 Javascript
jQuery快速上手:写jQuery与直接写JS的区别详细解析
Aug 26 Javascript
jQuery基础知识小结
Dec 22 Javascript
javascript事件模型介绍
May 31 Javascript
js数组的五种迭代方法及两种归并方法(推荐)
Jun 14 Javascript
JS中动态创建元素的三种方法总结(推荐)
Oct 20 Javascript
jQuery电话号码验证实例
Jan 05 Javascript
node.js 中间件express-session使用详解
May 20 Javascript
深入理解ES7的async/await的用法
Sep 09 Javascript
Vue实现移动端页面切换效果【推荐】
Nov 13 Javascript
angula中使用iframe点击后不执行变更检测的问题
May 10 Javascript
JavaScript利用html5新方法操作元素类名详解
Nov 27 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
德生PL450的电路分析和低放电路的改进办法
2021/03/02 无线电
php下使用strpos需要注意 === 运算符
2010/07/17 PHP
CI框架中集成CKEditor编辑器的教程
2014/06/09 PHP
谈谈从phpinfo中能获取哪些值得注意的信息
2017/03/28 PHP
php实现与python进行socket通信的方法示例
2017/08/30 PHP
google 搜索框添加关键字实现代码
2010/04/24 Javascript
JS滚轮事件onmousewheel使用介绍
2013/11/01 Javascript
JS判断对象是否存在的10种方法总结
2013/12/23 Javascript
函数式 JavaScript(一)简介
2014/07/07 Javascript
JavaScript数组随机排列实现随机洗牌功能
2015/03/19 Javascript
10条建议帮助你创建更好的jQuery插件
2015/05/18 Javascript
JavaScript对表格或元素按文本,数字或日期排序的方法
2015/05/26 Javascript
基于jQuery实现带动画效果超炫酷的弹出对话框(附源码下载)
2016/02/22 Javascript
Vue2.0 vue-source jsonp 跨域请求
2017/08/04 Javascript
jQuery选择器之表单元素选择器详解
2017/09/19 jQuery
Vue递归组件+Vuex开发树形组件Tree--递归组件的简单实现
2019/04/01 Javascript
bootstrap-table formatter 使用vue组件的方法
2019/05/09 Javascript
JS正则表达式验证端口范围(0-65535)
2020/01/06 Javascript
ES6函数实现排它两种写法解析
2020/05/13 Javascript
[03:57]DOTA2英雄梦之声_第03期_幻影刺客
2014/06/21 DOTA
[48:12]Secret vs Optic Supermajor 胜者组 BO3 第三场 6.4
2018/06/05 DOTA
python去掉字符串中重复字符的方法
2014/02/27 Python
python 实现登录网页的操作方法
2018/05/11 Python
PIL图像处理模块paste方法简单使用详解
2019/07/17 Python
余弦相似性计算及python代码实现过程解析
2019/09/18 Python
7款设计巧妙的css3飘带状3D立体效果的导航菜单和表单窗口
2013/02/04 HTML / CSS
欧姆龙医疗欧洲有限公司:Omron Healthcare Europe B.V
2020/06/13 全球购物
实习生体会的自我评价范文
2013/11/28 职场文书
监督检查工作方案
2014/05/28 职场文书
产品调价通知函
2015/04/20 职场文书
解放思想大讨论活动总结
2015/05/09 职场文书
运动员入场词
2015/07/18 职场文书
学习新党章心得体会2016
2016/01/15 职场文书
《夸父追日》教学反思
2016/02/20 职场文书
Go语言安装并操作redis的go-redis库
2022/04/14 Golang
mysql sock文件存储了什么信息
2022/07/15 MySQL