深入了解Vue自定义事件

  • 更新时间:2020-03-13 12:26:41
  • 编辑:能宏逸

前面的话

父组件使用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自定义事件(详解)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持码农之家。

相关教程

  • vue主动刷新页面及列表数据删除后的刷新实例

    今天小编就为大家分享一篇vue主动刷新页面及列表数据删除后的刷新实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧

    发布时间:2019-07-23

  • vue 地图可视化 maptalks 篇实例代码详解

    这篇文章主要介绍了vue 地图可视化 maptalks 篇,本文分步骤通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值 ,需要的朋友可以参考下

    发布时间:2019-07-25

  • Vue.js实战

    Vue.js实战

    尤雨溪推荐 随书附赠示例代码下载资源 vue社区iView组件贡献者 前端大神梁灏编写 突出实战 应用为王 大鹏展趐 鹰击长空 Vue.js实战助你攀上前端之巅

    大小:196.7 MBVue电子书

  • Vue.js项目实战

    Vue.js项目实战

    Vue实用、灵便、更快,为搭建详细的当代Web运用出示了需要的全部作用,其渐进式的特性也让开发人员可以轻轻松松入门,发布后快速获得了前端工程师工作人员的亲睐。这书由Vue.js关键精英

    大小:141 MBVue

  • 水晶石技法VUE 10完全学习手册

    水晶石技法VUE 10完全学习手册

    《水晶石技法 VUE 10完全学习手册》共14章,以实例为主,共提供了50多个制作实例。第1~3章对VUE进行了总体介绍。第4~12章通过大量的实例,分别介绍了VUE的各个功能模块,包括大气、材质、地形、生态系统、函数、动画、渲染,以及VUE和其他软件的结合使用(比如,3ds Max、Poser等)。第13章安排了两个综合实例,让读者在较为全面地了解了VUE的功能之后,综合使用各个知识点来完成更为大型的实例。在本书最后的第14章中,列出了VUE使用过程中的一些常见

    大小:114191 MB VUE10学习手册

  • Spring Boot+Vue全栈开发实战

    Spring Boot+Vue全栈开发实战

    传统的JavaEE开发效率低下、配置臃肿、调试不便,严重制约了程序员的生产力。Spring Boot致力于简化开发配置,并为企业级开发提供一系列非业务性功能;而Vue则采用数据驱动视图的方式将程序

    大小:196.3 MBSpring电子书

  • JavaScript+Vue+React全程实例

    JavaScript+Vue+React全程实例

    这书根据基础知识与开发实践活动紧密结合的观念,选萃当今简易、好用和时兴的百余个JavaScript编码案例,协助阅读者学习培训把握JavaScript开发语言。本书內容详实、重中之重突显、浅显易懂,包含了JavaScript前端开发开发的各个方面。

    大小:59150 MB MJS实例

  • 前端工程师必备技能:Vue移动开发实战技巧

    前端工程师必备技能:Vue移动开发实战技巧

    Vue.js是一个渐进式的JavaScript 框架,与其他重量级框架不同的是,Vue 采用自底向上增量开发的设计。Vue 的核心库只关注视图层,它不仅易于上手,还便于与第三方库或既有项目整合。作为201

    大小:122 MBVue实战电子书

  • Vue.js快速入门

    Vue.js快速入门

    目前单页应用框架层出不穷,其中Vue.js是十分耀眼的项目之一,受到国内外开发人员的极度推崇。

    大小:186.6 MBWeb前端电子书

  • Vue企业开发实战

    Vue企业开发实战

    本书以Vue.js 2为基础,以项目实战的方式引导读者渐进式学习Vue.js框架。本书分为项目起步、Vue.js介绍、项目插件、项目梳理等部分。

    大小:109.6 MBVue.js实战电子书

用户留言