Vue.js组件通信之自定义事件详解


Posted in Javascript onOctober 19, 2019

组件通信

从父组件向子组件通信,通过props传递数据就可以了,但Vue组件通信的场景不止有这一种,归纳起来,组件之间的通信可以用下图来表示:

Vue.js组件通信之自定义事件详解

自定义事件

当子组件需要向父组件传递数据时,就要用到自定义事件。子组件用**$ emit()来触发事件**,父组件用**$ on()**来监听子组件的事件。

父组件也可以直接在子组件的自定义标签上使用v-on来监听子组件触发的事件。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <script src="https://unpkg.com/vue/dist/vue.js"></script>
  <title>自定义事件</title>
</head>
<body>
  <div id="app">
    <p>总数:{{total}}</p>
    <my-component
      @increase="handleGetTotal"
      @reduce="handleGetTotal"></my-component>
  </div>
  <script>
    Vue.component('my-component',{
      template: '\
        <div>\
          <button @click="handleIncrease">+1</button>\
          <button @click="handleReduce">-1</button>\
        </div>',
      data: function () {
        return {
          counter: 0
        }
      },
      methods: {
        handleIncrease: function () {
          this.counter++;
          this.$emit('increase', this.counter);
        },
        handleReduce: function () {
          this.counter--;
          this.$emit('reduce', this.counter);
        }
      }
    });

    var app = new Vue({
      el: '#app',
      data: {
        total: 0
      },
      methods: {
        handleGetTotal: function (total) {
          this.total = total;
        }
      }
    });
  </script>
</body>
</html>

Vue.js组件通信之自定义事件详解

子组件有两个按钮,分别实现+1和-1的效果,在改变组件的data “counter”后,通过$emit()在把它传递给父组件,父组件使用v-on:increase和v-on:reduce监听事件。

$emit()方法的第一个参数是自定义事件的名称,后面的参数是要传递的数据,可以不填或者填写多个。

注意:除了用v-on在组件上监听自定义事件外,也可以监听DOM事件,这时候可以用 .native修饰符表示监听的是一个原生事件,监听的是该组件的根元素:

<my-component v-on:click.native="handleClick"></my-component>

使用v-model

Vue 2.x 可以在自定义组件上使用v-model指令。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <script src="https://unpkg.com/vue/dist/vue.js"></script>
  <title>使用v-model</title>
</head>
<body>
  <div id="app">
    <p>总数:{{total}}</p>
    <my-component v-model="total"></my-component>
  </div>
  <script>
    Vue.component('my-component',{
      template: '<button @click="handleClick">+1</button>',
      data: function () {
        return {
          counter: 0
        }
      },
      methods: {
        handleClick: function () {
          this.counter++;
          this.$emit('input',this.counter);
        }
      }
    });

    var app = new Vue({
      el: '#app',
      data: {
        total: 0
      }
    });
  </script>
</body>
</html>

仍然是点击按钮+1的效果,不过这次组件$emit()的事件是特殊的input,在使用组件的父级,并没有在<my-component>上使用@input=“handler”,而是使用了v-model板顶的一个数据total。这也可以称作是一个语法糖,因为上面的示例可以间接地用自定义事件来实现:

<div id="myApp">
  <p>总数:{{total}}</p>
  <my-component1 @input="handlegetTotal"></my-component1>
</div>
<script>
  Vue.component('my-component1',{
    template: '<button @click="handleClick">+1</button>',
    data: function () {
      return {
        counter: 0
      }
    },
    methods: {
      handleClick: function () {
        this.counter++;
        this.$emit('input',this.counter);
      }
    }
  });

  var myApp = new Vue({
    el: '#myApp',
    data: {
      total: 0
    },
    methods: {
      handlegetTotal: function (value) {
        this.total = value;
      }
    }
  });
</script>

v-model还可以用来创建自定义的表单输入组件,进行数据双向绑定:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <script src="https://unpkg.com/vue/dist/vue.js"></script>
  <title>自定义表单输入组件</title>
</head>
<body>
  <div id="app">
    <p>总数:{{total}}</p>
    <my-component v-model="total"></my-component>
    <button @click="handleReduce">-1</button>
  </div>
  <script>
    Vue.component('my-component',{
      props: ['value'],
      template: '<input :value="value" @input="updateValue">',
      methods: {
        updateValue: function (event) {
          this.$emit('input', event.target.value);
        }
      }
    });

    var app = new Vue({
      el: '#app',
      data: {
        total: 0
      },
      methods: {
        handleReduce: function () {
          this.total--;
        }
      }
    });
  </script>
</body>
</html>

Vue.js组件通信之自定义事件详解

注意:实现这样一个具有双向绑定的v-model组件要满足下面的两个要求:

  • 接受一个value属性
  • 在有新的value时触发input事件

更多教程点击《Vue.js前端组件学习教程》,欢迎大家学习阅读。

关于vue.js组件的教程,请大家点击专题vue.js组件学习教程进行学习。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
jQuery+ajax实现顶一下,踩一下效果
Jul 17 Javascript
基于Jquery插件开发之图片放大镜效果(仿淘宝)
Nov 19 Javascript
select标签模拟/美化方法采用JS外挂式插件
Apr 01 Javascript
asm.js使用示例代码
Nov 28 Javascript
Jquery 实现grid绑定模板
Jan 28 Javascript
jQuery遍历json的方法分析
Apr 16 Javascript
EasyUI的DataGrid每行数据添加操作按钮的实现代码
Aug 22 Javascript
AngularJS模糊查询功能实现代码(过滤内容下拉菜单排序过滤敏感字符验证判断后添加表格信息)
Oct 24 Javascript
Vue-Access-Control 前端用户权限控制解决方案
Dec 01 Javascript
自定义vue组件发布到npm的方法
May 09 Javascript
JavaScript基础之静态方法和实例方法分析
Dec 26 Javascript
javascript Number 与 Math对象的介绍
Nov 17 Javascript
Vue.js自定义指令学习使用详解
Oct 19 #Javascript
Vue.js标签页组件使用方法详解
Oct 19 #Javascript
基于JavaScript获取base64图片大小
Oct 18 #Javascript
react MPA 多页配置详解
Oct 18 #Javascript
vue滚动插件better-scroll使用详解
Oct 18 #Javascript
VUE实现密码验证与提示功能
Oct 18 #Javascript
VUE实现图片验证码功能
Nov 18 #Javascript
You might like
什么是调频(FM)、调幅(AM)、短波(SW)、长波(LW)
2021/03/01 无线电
php代码收集表单内容并写入文件的代码
2012/01/29 PHP
php如何控制用户对图片的访问 PHP禁止图片盗链
2016/03/25 PHP
小程序微信退款功能实现方法详解【基于thinkPHP】
2019/05/05 PHP
Nigma vs AM BO3 第一场2.13
2021/03/10 DOTA
IE中直接运行显示当前网页中的图片 推荐
2006/08/31 Javascript
js调试工具 Javascript Debug Toolkit 2.0.0版本发布
2008/12/02 Javascript
基于JQuery的密码强度验证代码
2010/03/01 Javascript
JS分割字符串并放入数组的函数
2011/07/04 Javascript
修改file按钮的默认样式实现代码
2013/04/23 Javascript
Jjcarousellite 实现图片列表滚动的简单实例
2013/11/29 Javascript
jQuery实现ctrl+enter(回车)提交表单
2015/10/19 Javascript
jQuery实现页面下拉100像素出现悬浮窗口的方法
2016/09/05 Javascript
ReactNative之键盘Keyboard的弹出与消失示例
2017/07/11 Javascript
javascript基础进阶_深入剖析执行环境及作用域链
2017/09/05 Javascript
利用Three.js如何实现阴影效果实例代码
2017/09/26 Javascript
js Dom实现换肤效果
2017/10/21 Javascript
使用Bootstrap + Vue.js实现表格的动态展示、新增和删除功能
2017/11/27 Javascript
jquery如何实现点击空白处隐藏元素
2017/12/05 jQuery
JS基于封装函数实现的表格分页完整示例
2018/06/26 Javascript
Python基于ThreadingTCPServer创建多线程代理的方法示例
2018/01/11 Python
儿童python练习实例
2018/05/27 Python
django中模板的html自动转意方法
2018/05/27 Python
Python设计模式之工厂方法模式实例详解
2019/01/18 Python
关于torch.optim的灵活使用详解(包括重写SGD,加上L1正则)
2020/02/20 Python
Farfetch台湾官网:奢侈品牌时尚购物平台
2019/06/17 全球购物
大学英语演讲稿(中英文对照)
2014/01/14 职场文书
实习生求职自荐信
2014/02/07 职场文书
《长城》教学反思
2014/02/14 职场文书
2014两会学习心得:榜样精神伴我行
2014/03/17 职场文书
农村葬礼主持词
2014/03/31 职场文书
股权转让协议书
2014/04/12 职场文书
陕西导游词
2015/02/04 职场文书
音乐会主持人开场白
2015/05/28 职场文书
2016大学生社会实践心得体会范文
2016/01/14 职场文书
优秀家长事迹材料(2016推荐版)
2016/02/29 职场文书